Wednesday, August 21, 2013

Symfony2 : Error Log

An exception has been thrown during the compilation of a template ("You must add ASFTaskBundle to the assetic.bundle config to use the {% stylesheets %} tag in ASFTaskBundle:Default:template-base.html.twig. (currently enabled: ASFPembedaBundle)") in "ASFTaskBundle:Default:template-base.html.twig". 

 

add to the app/config/config.yml

 

 assetic:
    debug:          %kernel.debug%
    use_controller: false
#    bundles:        [ASFPembedaBundle]
    bundles:
           - ASFPembedaBundle
           - ASFTaskBundle
    #java: /usr/bin/java

-

Simple Form

? php app/console generate:bundle --namespace=ASF/TaskBundle
 
 
                                            
  Welcome to the Symfony2 bundle generator  
                                            


In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest ASFTaskBundle.

Bundle name [ASFTaskBundle]: 

The bundle can be generated anywhere. The suggested default directory uses
the standard conventions.

Target directory [/home/fadabi/www/asf/asfnetwork/symfony2/src]: 

Determine the format to use for the generated configuration.

Configuration format (yml, xml, php, or annotation): yml

To help you get started faster, the command can generate some
code snippets for you.

Do you want to generate the whole directory structure [no]? yes

                             
  Summary before generation  
                             

You are going to generate a "ASF\TaskBundle\ASFTaskBundle" bundle
in "/home/fadabi/www/asf/asfnetwork/symfony2/src/" using the "yml" format.

Do you confirm generation [yes]? 

                     
  Bundle generation  
                     

Generating the bundle code: OK
Checking that the bundle is autoloaded: OK
Confirm automatic update of your Kernel [yes]? 
Enabling the bundle inside the Kernel: OK
Confirm automatic update of the Routing [yes]? 
Importing the bundle routing resource: OK

                                               
  You can now start using the generated code!  
 
 
==> Creating module / Entity 
vi src/ASF/TaskBundle/Entity/Task.php
 
<?php
// src/ASF/TaskBundle/Entity/Task.php 
namespace ASF\TaskBundle\Entity;

// para el mapping entre campos de la BD y Entity 
use Doctrine\ORM\Mapping as ORM;

/** 
 * @ORM\Entity 
 * @ORM\Table(name="task") 
 */

class Task2
{
   /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", unique=true) 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */
    protected $id;

    /** 
     * El nombre de la tarea, como máximo de 20 caracteres 
     * @ORM\Column(type="string", length=20) 
     */
     protected $task;

    /** 
     * La fecha de finalización de la tarea 
     * @ORM\Column(type="date") 
     */
     protected $dueDate;

    /** 
     * La descripción de la tarea 
     * @ORM\Column(type="text", length=300) 
     */
     protected $description;

    /** 
     * La URL relacionada de algún modo con la tarea 
     * @ORM\Column(type="text", nullable=true) 
     */
     protected $url;
 
==> Generating Getters & Setters
? php app/console doctrine:generate:entities ASF/TaskBundle/Entity/Task
Generating entity "ASF\TaskBundle\Entity\Task"
  > backing up Task.php to Task.php~
  > generating ASF\TaskBundle\Entity\Task


==> Form validation :
#ASF/TaskBundle/Resource/config/validation.yml
ASF\TaskBundle\Entity\Task:
   properties:
      task:
          - NotBlank: {message: "Tak Boleh Kosong"}
          - MaxLength: {limit: 20, message: "Maksima {{ limit }} huruf" }
          - MinLength: {limit: 1, message: "minima {{ limit }} huruf" }
      dueDate:
          - NotBlank: ~
          - Type: \DateTime
          - Date: {message: "Tarikh Kosong"}
      description:
          - MaxLength: { limit: 300, message: "Desc Maksima {{ limit }} huruf" }
      url:
          - Url:
          - Regex:
               pattern: "/.*\.es$/"
               message: "La URL debe terminar en .es"


==> creating the table

php app/console doctrine:schema:update --force

==> the routing

# src/ASF/TaskBundle/Resources/config/routing.yml
ASFTaskBundle_task_new:
   pattern: /new
   defaults: { _controller: ASFTaskBundle:Default:new }

ASFTaskBundle_task_show:
   pattern: /show
   defaults: { _controller: ASFTaskBundle:Default:show }

ASFTaskBundle_task_edit:
   pattern: /{id}/edit
   defaults: { _controller: ASFTaskBundle:Default:edit, id: 0 }
   requirements:
        id: \d+

ASFTaskBundle_task_success:
   pattern: /success/{nombreTarea}
   defaults: { _controller: ASFTaskBundle:Default:success, nombreTarea: - }


==> The Controller








php app/console doctrine:schema:update --force




<?php  
// src/ASF/TaskBundle/Controller/DefaultController.php

namespace ASF\TaskBundle\Controller;
use ASF\TaskBundle\Entity\Task;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    /*
     * new Task
     */
     public function newAction(Request $request)
     {
        // Current year:
        $thisyear = date('Y');

        // create new task
        $task = new Task();
        $form = $this->createFormBuilder($task)
            ->add('task', 'text',array('label' => 'Tarea:'))
            ->add('dueDate', 'date', array('label' => 'Fetch limit', 'years' => range($thisyear, $thisyear+5)))
                  ->add('description', 'textarea', array('label' => 'Descripcion', 'required' => 'false'))
                  ->add('url', 'url', array('required' => false))
             ->getForm();  

        if ($request->getMethod() == 'POST') {
            // second time you call NewAction, now we have the data
            // task in the $request. So do the "bind" the form...
            $form->bindRequest($request);  
            // and check whether it is valid (validation.yml!)
            if ($form->isValid()){
                  // do things with form data.
                  // Keep them in BD, p eg.  
                  $em = $this->getDoctrine()->getEntityManager();
                  $em->persist($task); // = tell Symfony to "control" this object!
                  $em->flush(); // can group multiple queries and then flush the launch of the BD at a time!  
                  return $this->redirect($this->generateUrl('
ASFTaskBundle_task_success', array('nombreTarea' => $task->getTask()) ));
              }
         }  
         return $this->render('
ASFTaskBundle:Default:new2desplegado.html.twig', array( 'form' => $form->createView(), ));
    }  

    /*
     * Gets all tasks
     */ public function showAction() {
            $tasks = $this->getDoctrine()
                     ->getRepository('
ASFTaskBundle:Task')
                     ->findAll();
                      //->findByTask('Ejemplo tarea'); //with this line could find a job with that nombre exacto  
                      return $this->render('
ASFTaskBundle:Default:show.html.twig', array(
                           'tasks' => $tasks
                      ));
            }

     /*
      * Edit a task
      */
      public function editAction($id, Request $request)
      {
          if (!$id) {
              throw $this->createNotFoundException('Can not find the task id = '.$id);
          }

         // valid that there is a task associated with that ID...
         $em = $this->getDoctrine()->getEntityManager();
         $task = $em->getRepository('
ASFTaskBundle:Task')->find($id);
         if (!$task){
            throw $this->createNotFoundException('No se encuentra la tarea con id = '.$id);
         }
  
         // I want to know the current year:
         $thisyear = date('Y');  

         // I think the form (with fields) dynamically.
         // As I will repeat the form that you created in NewAction, it might be interesting
         // plantearme create a separate class and use $ this->createForm to create "statically"
         $form = $this->createFormBuilder($task)
                 ->add('task', 'text',array('label' => 'Tarea:'))
                 ->add('dueDate', 'date', array('label' => 'Fetch limit', 'years' => range($thisyear, $thisyear+5)))
                 ->add('description', 'textarea', array('label' => 'Descripcion', 'required' => 'false'))
                 ->add('url', 'url', array('required' => false))
                 ->getForm();  
          
          if ($request->getMethod() == 'POST') {
                 // I have received the result of the form... 

                 // mappeo request values ​​to the form...
                 $form->bindRequest($request);
  
                 // and check whether it is valid ...
                 if ($form->isValid()){
                    // is valid, so update the BD ...
                    $em->flush();
                    return $this->redirect($this->generateUrl('
ASFTaskBundle_task_success', array('nombreTarea' => $task->getTask()) ));
                 }
          }  

          // FIRST INVOCATION TO EDIT: you have to let the user change the info!
          return $this->render('
ASFTaskBundle:Default:edit2desplegado.html.twig', array(
                     'form' => $form->createView(),
                     'id' => $task->getId(),
          ));
    }  

    /*
     * Show splash screen "when performing operations success."
     */
     public function successAction($nombreTarea){
          if (!strcmp($nombreTarea,"-")){
                 $message = "What frames, Moreno?URL should not invoke this manually!";
          } else {
                // I will generate a message...
                $message = "task '".$nombreTarea."' is saved.";
          }  
          return $this->render('
ASFTaskBundle:Default:success.html.twig', array(
                      'message' => $message ));
     }


The Templates (view) + Assets (Css)
==>  The Templates (view) + Assets (Css)

vi src/ASF/TaskBundle/Resources/views/Default/template-base.html.twig

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
{% block head %}
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>
      {% block title %}
         {{ title|default("Template Base para TWIG") }}
      {% endblock title %}
   </title>    

   {% block description %}
   <meta name="description" content="{{ description|default('Plantilla TWIG base por Miguel Martin') }}"/>
   {% endblock description %}  

   {% block keywords %}
   <meta name="keywords" content="twig, template, free, design, 960, grid" />
   {% endblock keywords %}  

   {% block styles %}
      {% stylesheets
         '@ASFTaskBundle/Resources/public/css/layout/mainStyle.css'
         '@ASFTaskBundle/Resources/public/css/layout/reset.css'
         '@ASFTaskBundle/Resources/public/css/layout/colors.css'
         output = 'css/compiled/styles.css'
         filter = 'yui_css'
         %}
         <link href="{{ asset_url }}" type="text/css" rel="stylesheet" media="screen" />
       {% endstylesheets %}
   {% endblock styles %}  

   {% block script %}
      {% javascripts
          '@ASFTaskBundle/Resources/public/js/*'
      %}
      <script src="{{ asset_url }}" type="text/javascript"></script>
   {% endjavascripts %}  
   <script type="text/javascript">
   //<![CDATA[
      //$(document).ready(function(){  

      //});
   //]]>
   </script>
  {% endblock script %}
</head>
{% endblock head %}  

<body>
<div id="wrapper">  
<!-- ******************************************** HEADER ************************************ -->  

{% block header %}
    <div id="header">
        <div id="titulo-centro">
            <h1> {{ titulo|default("TEMPLATE BASE") }}</h1>
        </div>
    </div>
{% endblock header %}
<!-- ******************************************** /HEADER ************************************ -->    

<div id="content">  
    <div id="breadcrumbs">
       {% block breadcrumbs %}
         <ul>
             <li class"=first"><a href="{{ path('
ASFTaskBundle_homepage') }}">HOME </a></li>
             <li class="actual"><a href="="{{ path('
ASFTaskBundle_test_template') }}">Template</a></li>
         </ul>
       {% endblock breadcrumbs %}
    </div>
    <br />  

<!-- ******************************************** LEFT-COLUMN ************************************ -->
<div id="left-column">
   {% block menusub %}
      <div id="menu-sub">
         <ul>
           <li class"=first"><a href="{{ path('
ASFTaskBundle_homepage') }}">HOME </a></li>
           <li class="actual"><a href="{{ path('
ASFTaskBundle_test_template') }}">Template</a></li>  
           <li><a href="{{ path('
ASFTaskBundle_task_new2') }}">Insertar tarea</a></li>
           <li><a href="{{ path('
ASFTaskBundle_task_show') }}">Mostrar tareas</a></li>
           <li class="last"><a href="#">link 4</a></li>
         </ul>
      </div>
    {% endblock menusub %}
</div>

<!-- ******************************************** /LEFT-COLUMN ************************************ -->  

<!--====MAIN COLUMN START====-->
<div id="main-column">
    {% block maincolumn %}  
       <h2>Template base en TWIG</h2>
       <br />
       <p class="text-justify">We will be important, interesting, but because occasionally circumstances occur in which toil and pain can procure him some great. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it. We currently have in the train comes to find fault with that produces no resultant pleasure is to be online applications. These cases are perfectly account of the system, they are at fault quae workshop to leave softens recommend you: </ p> <br />
       <p class="text-justify"> But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and, a complete account of the system, and the very fact that explorer from the truth, the master of a happy life that were said to you here. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because they do not know how to pursue pleasure rationally encounter consequences that are a pain. Nor again is there anyone who loves grief itself since it is grief liver, brain, so blinded by desire, but because occasionally occur at times of such a nature in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?
</p>    

    {% endblock maincolumn %}
</div>  
<!--====MAIN COLUMN END====-->

<!--====RIGHT COLUMN START====-->
   <div id="right-column">
   {% block rightcolumn %}  
       <p class="text-justify xxsmall">But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it?</p>  
    {% endblock rightcolumn %}
</div>  
<!--====RIGHT COLUMN END====-->  
</div>  

<!--=================CONTENT END==============-->  

<!--=================FOOTER START==============-->  

<div id="footer">
    {% block footer %} &copy;2012 All Rights Reserved Miguel Martin | <a href="http://www.leccionespracticas.com" target="_blank" >Design by MiguelMartin</a> | <a href="http://validator.w3.org/check?uri=referer" target="_blank" rel="nofollow" >XHTML</a> | <a href="http://jigsaw.w3.org/css-validator/" target="_blank" rel="nofollow" >CSS</a>
</div>
{% endblock footer %}  

<!--=================FOOTER END==============-->
</div>
</body>
</html>



vi src/ASF/TaskBundle/Resources/views/Default/new2desplegado.html.twig


{# src/ASF/TaskBundle/Resources/views/Default/new2desplegado.html.twig #}
{% extends "ASFTaskBundle:Default:template-base.html.twig" %}

{% block title %}
    Insert New Task
{% endblock title %}  

{% block header %}
   <div id="header">
      <div id="titulo-centro"> <h1>INSERT NEW TASK</h1>
      </div>
   </div>
{% endblock header %}  

{% block breadcrumbs %}
    <ul>
      <li class"=first"><a href="/">HOME </a></li>
      <li class="actual"><a href="/
ASF/template">Template</a></li>
      <li class="last"><a href="/
ASF/new2">Nueva tarea</a></li>  
    </ul>
{% endblock breadcrumbs %}  

{% block maincolumn %}  
    {% block message %}  
    {% endblock message %}  
       <div id="form-div" style="width: 800px; margin:auto; padding:10px;">
          <form action="{{ path('
ASFTaskBundle_task_new2') }}" method="post" {{ form_enctype(form) }}>  

          <div id="errores_form" class="error">
             <!-- general errors of the form -->
             {{ form_errors(form) }}
          </div>  
        <div id="formcontent">
            <table style="border-collapse:separate; border-spacing:1em;">
                <tr>
                    <td>{{ form_label(form.task) }}</td>
                    <td>{{ form_widget(form.task) }}</td>
                    <td class="error">{{ form_errors(form.task) }}</td>
                </tr>
                <tr>
                     <td>{{ form_label(form.dueDate) }}</td>
                     <td>{{ form_widget(form.dueDate) }}</td>
                     <td class="error">{{ form_errors(form.dueDate) }}</td>
                </tr>
                <tr>
                     <td>{{ form_label(form.description) }}</td>
                     <td>{{ form_widget(form.description) }}</td>
                     <td class="error">{{ form_errors(form.description) }}</td>
                </tr>
                <tr>
                     <td>{{ form_label(form.url) }}</td>
                     <td>{{ form_widget(form.url) }}</td>
                     <td class="error">{{ form_errors(form.url) }}</td>
                </tr>
                <tr></tr>
                <tr>{{ form_rest(form) }}</tr>
                <tr>
                    <td></td>
                    <td><input type="submit" formnovalidate /></td>
                </tr>  
            </table>
         </div>  
         <br />
     </form>
</div>
{% endblock maincolumn %}  

{% block rightcolumn %}
    <p>Use this form to enter a new task</p>
{% endblock rightcolumn %}


vi src/ASF/TaskBundle/Resources/views/Default/show.html.twig


{% extends "ASFTaskBundle:Default:new2desplegado.html.twig" %}
{% block title %}
    List of tasks
{% endblock title %}
{% block header %}
    <div id="header">
        <div id="titulo-centro">
            <h1>MOSTRAR TAREAS</h1>
        </div>
    </div>
{% endblock header %}  
{% block breadcrumbs %}
    <ul>
       <li class"=first"><a href="/">HOME </a></li>
       <li class="actual"><a href="/
ASF/template">ASF</a></li>
       <li class="last">Mostrar tareas</li>
    </ul>
{% endblock breadcrumbs %}  

{% block maincolumn %}
   {% block message %}
      {% if tasks is defined %}
         <table style="border-spacing: 5px; margin-right: 5px; border-collapse: separate;">
           <tr style="font-weight: bold;">
              <td></td>
              <!-- editar -->
              <!--<td>ID</td>-->
              <td>NOMBRE</td>
              <td>FECHA</td>
              <td>DESCRIPCI&Oacute;N</td>
              <td>URL</td> 
           </tr>
      {% for tarea in tasks %}
           <tr style="font-size: 0.8em">
              <td><a href=" {{ path('
ASFTaskBundle_task_edit', { 'id' : tarea.id } ) }}" style="color:#A90641; font-size:0.9em; ">edit</a></td>
              <!-- editar -->
              <!--<td>{{ tarea.id }}</td>-->
              <td>{{ tarea.task }}</td>
              <td>{{ tarea.dueDate|date("m/d/Y") }}</td>
              <td>{{ tarea.description }}</td>
              <td>{{ tarea.url }}</td>  
           </tr>
      {% endfor %}
      </table>
    {% else %}
        <p>No tasks. you <a href="{{ path('
ASFTaskBundle_task_new2') }}">Insert a new task</a></p>
    {% endif %}  
{% endblock message %}
{% endblock maincolumn %}  
{% block rightcolumn %}  
{% endblock rightcolumn %}

vi src/ASF/TaskBundle/Resources/views/Default/success.html.twig


{% extends "ASFTaskBundle:Default:new2desplegado.html.twig" %}  

{% block title %}
    job Stored
{% endblock title %}  

{% block header %}
    <div id="header">
        <div id="titulo-centro">
             <h1>Tarea guardada</h1>
        </div>
    </div>
{% endblock header %}    

{% block breadcrumbs %}
    <ul>
        <li class"=first"><a href="/">HOME </a></li>
        <li class="actual"><a href="/
ASF/template">Template</a></li>
        <li class="last">Tarea completada</li>
    </ul>
{% endblock breadcrumbs %}  

{% block maincolumn %}

   {% block message %}
      {{ message|raw }}
         <br /><br />
         <p>Use the links in the menu to perform a new task or view existing tasks</p>
   {% endblock message %}
{% endblock maincolumn %}



vi src/ASF/TaskBundle/Resources/views/Default/edit2desplegado.html.twig


{# src/ASF/TaskBundle/Resources/views/Default/new2desplegado.html.twig #}
{% extends "ASFTaskBundle:Default:template-base.html.twig" %}

{% block title %}
   modify Task
{% endblock title %}  

{% block header %}
   <div id="header">
      <div id="titulo-centro">
         <h1>MODIFY TASK</h1>
      </div>
   </div>
{% endblock header %}  

{% block breadcrumbs %}
   <ul>
      <li class"=first"><a href="/">HOME </a></li>
      <li class="actual"><a href="/
ASF/template">Template</a></li>
      <li class="last">Editar tarea</li>  
   </ul>
{% endblock breadcrumbs %}  

{% block maincolumn %}  
   {% block message %}  
   {% endblock message %}  
   <div id="form-div" style="width: 800px; margin:auto; padding:10px;">
      <form action="{{ path('
ASFTaskBundle_task_edit', { 'id' : id } ) }}" method="post" {{ form_enctype(form) }}>  
      <div id="errores_form" class="error">
         <!-- general errors of the form -->
         {{ form_errors(form) }}
      </div>  
      <div id="formcontent">
         <table style="border-collapse:separate; border-spacing:1em;">
            <tr>
               <td>{{ form_label(form.task) }}</td>
               <td>{{ form_widget(form.task) }}</td>
               <td class="error">{{ form_errors(form.task) }}</td>
            </tr>
            <tr>
                <td>{{ form_label(form.dueDate) }}</td>
                <td>{{ form_widget(form.dueDate) }}</td>
                <td class="error">{{ form_errors(form.dueDate) }}</td>
            </tr>
            <tr>
                <td>{{ form_label(form.description) }}</td>
                <td>{{ form_widget(form.description) }}</td>
                <td class="error">{{ form_errors(form.description) }}</td>
            </tr>
            <tr>
                 <td>{{ form_label(form.url) }}</td>
                 <td>{{ form_widget(form.url) }}</td>
                 <td class="error">{{ form_errors(form.url) }}</td>
            </tr>
            <tr></tr>
            <tr>{{ form_rest(form) }}</tr>
            <tr>
                <td></td>
                <td><input type="submit" formnovalidate /></td>
            <tr>   </table> </div>  
            <br />
         </form>
      </div>
{% endblock maincolumn %}  
{% block rightcolumn %}
   <p>Use the form to edit the new task</p>
{% endblock rightcolumn %}


vi src/ASF/TaskBundle/Resources/public/css/layout/reset.css

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}

vi src/ASF/TaskBundle/Resources/public/css/layout/colors.css


a{color:#A90641}a:hover{color:#A90641}a:visited{color:#A90641}a:active{color:#A90641} body{ background:#464646; color:#333;} #content{ color:#EEE; font-size: 0.8em;background-color: #343333;} #header{color:#FCFAD0;border-bottom:thick double #A90641;background:#111;}#footer{font-size:0.7em;border-top:thick double #A90641;background: #111;color:#5B605F;font-weight:bold;}#menu-sub a{font-size:0.8em; color:#A90641;}#menu-sub {padding-left:5px;}#menu-sub a:hover{font-size:0.8em; color:#CB2863;}#menu-sub a:visited{font-size:0.8em; color:#A90641;}#titulo-centro{margin:auto; width: 920px;padding:20px;text-align:center;}#breadcrumbs a{color:#A90641}.actual a{font-weight:bold;}


 vi src/ASF/TaskBundle/Resources/public/css/layout/mainStyle.css

.tt1 {background:#FF0000;}
.tt2 {background:#FF00FF;}
.tt3 {background:#FFFF00;}  

html { }  

body {font: 13px/1.5 Verdana, Arial, sans-serif; background:url(../_images/bck2.jpg) 50% 0 repeat-x;}  
a:focus {outline: 1px dotted invert;}  
a:link {color:#000; text-decoration:none;}
a:visited {color:#000; text-decoration:none;}
a:hover {color:#000; text-decoration:none;}
a:active {color:#000; text-decoration:none;}  

#footer a:link {color:#666; text-decoration:none;}
#footer a:visited {color:#666; text-decoration:none;}
#footer a:hover {color:#666; text-decoration:none;}
#footer a:active {color:#666; text-decoration:none;}  

hr {border-color: #ccc; border-style: solid; border-width: 1px 0 0; clear: both; height: 0;}  

p { }
sup {position: relative;top: -3px;vertical-align: top;font-size: 80%;}
sub {position: relative;bottom: -5px;vertical-align: top;font-size: 80%;}  

h1 {font-size: 25px;}
h2 {font-size: 23px;}
h3 {font-size: 21px;}
h4 {font-size: 19px;}
h5 {font-size: 17px;}
h6 {font-size: 15px;}  

.xxsmall {font-size: 10px;}
.xsmall {font-size: 12px;}
.small {font-size: 14px;}
.medium {font-size: 16px;}
.large {font-size: 22px;}
.xlarge {font-size: 26px;}
.xxlarge {font-size: 32px;}  

ol {list-style: decimal;}
ul {list-style: square;}
li {margin-left: 30px;}  

p, dl, hr, h1, h2, h3, h4, h5, h6, ol, ul, pre, table, address, fieldset {margin-bottom: 20px;}  

#wrapper {overflow:hidden; width:960px; margin:20px auto;}  

html body * span.clear,html body * div.clear,html body * li.clear,html body * dd.clear{background:none;border:0;clear:both;display:block;float:none;font-size:0;list-style:none;margin:0;padding:0;overflow:hidden;visibility:hidden;width:0;height:0}  

.margin-left {margin-left:20px;}
.margin-right {margin-right:20px;}
.margin-top {margin-top:20px;}
.margin-bottom {margin-bottom:20px;}
.margin-left-half {margin-left:10px;}
.margin-right-half {margin-right:10px;}
.margin-top-half {margin-top:10px;}
.margin-bottom-half {margin-bottom:10px;}
.margin-bottom-none {margin-bottom:0;}  

img.centered {display:block;margin-left:auto;margin-right:auto;}
img.alignright {display: inline;}
img.alignleft {display: inline;}
.alignright {float:right;}
.alignleft {float:left;}  

.bold {font-weight:bold;}
.italic {font-style:italic;}
.text-left {text-align:left;}
.text-right {text-align:right;}
.uppercase {text-transform:uppercase;}
.text-justify{text-align:justify;}  

/*=================MAIN END==============*/  

/* BREADCRUMBS! */
#breadcrumbs {margin-left:160px;}
#breadcrumbs ul li{display: inline; }
#breadcrumbs ul li:before{ content:"\00BB \0020";}  

/*=================HEADER START==============*/  
#header {width:960px;float:left; min-height: 80px;}  
/*=================HEADER END==============*/  

/*=================CONTENT START==============*/  
#content {width:960px;float:left; padding-top:10px; padding-bottom: 10px;}  
/*======LEFT COLUMN START======*/  
#left-column {width:160px;float:left;}  
#menu-sub {float:left;}
#menu-sub ul {list-style:none;}
#menu-sub ul li {font-size:16px;}  
/*======LEFT COLUMN END======*/  

/*======MAIN COLUMN START======*/  
#main-column {width:630px;float:left;padding-right:10px;}  
/*======MAIN COLUMN END======*/    

/*======RIGHT COLUMN START======*/  
#right-column {width:140px;float:left;padding-left:10px; padding-right:10px;}  
/*======RIGHT COLUMN END======*/  
/*=================CONTENT END==============*/  

/*=================FOOTER START==============*/  
#footer {width:960px;float:left;text-align:center;color:#666; min-height:30px; padding: 15px;}  
/*=================FOOTER END==============*/


? app/console cache:clear --env=dev

? php app/console assets:install web


http://symfony2/web/app_dev.php/show

http://symfony2/web/app_dev.php/new



php app/console doctrine:schema:update --force
 
The Templates (view) + Assets (Css)
php app/console doctrine:generate:entities curso/TaskBundle/Entity/Task - See more at: http://www.leccionespracticas.com/informatica-web/symfony-create-and-update-an-entity-using-doctrine-full-example/#sthash.xitlSIsZ.dpuf
php app/console doctrine:generate:entities curso/TaskBundle/Entity/Task - See more at: http://www.leccionespracticas.com/informatica-web/symfony-create-and-update-an-entity-using-doctrine-full-example/#sthash.xitlSIsZ.dpuf

Tuesday, August 20, 2013

File System Fuction

use Symfony\Component\Finder\Finder;

$finder = new Finder();

$iterator = $finder
  ->files()
  ->name('*.php')
  ->depth(0)
  ->size('>= 1K')
  ->in(__DIR__);

foreach ($iterator as $file) {
    print $file->getRealpath()."\n";
}

Friday, August 16, 2013

Creating Bundle Basic With Database - super fast

For  Symfony2.3
1. Download Symfony2 Standard Edition
2. extract :
   tar -zxvf Symfony_Standard_Vendors_2.0.0BETA2.tgz
3. set permission :
   chmod 777 app/cache app/logs
4. Point your server to “web/” as root directory and you already would have to see symfony2 welcome page at http://127.0.0.1/app_dev.php/ 
5. setup database config:
   vi app/config/parameter.yml
6. Creating our first bundle
   php app/console generate:bundle --namespace=ASF/Bundle/StoreBundle --no-interaction

7. add to app/AppKernel.php
$bundles = array(
    // ...
    new ASF\StoreBundle\ASFStoreBundle(),
);
8. add to app/config/routing.yml
asf_store:
    resource: "@ASFStoreBundle/Resources/config/routing.yml"
    prefix:   /store
9. Creating a controller :
vi src/ASF/StoreBundle/Controller/StoreController.php
//ASF/StoreBundle/Controller/StoreController.php
<?php
namespace ASF\StoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class StoreController extends Controller
{
    /**
     * @Template()
     */
    public function indexAction($store)
    {
        return array('store' => $store);
    }
}
10. add to src/ASF/StoreBundle/Resources/config/routing.yml
asf_mystore:
    pattern:  /store/{store}
    defaults: { _controller: ASFStoreBundle:Store:index }
11. add a view
 vi src/ASF/StoreBundle/Resources/views/Store/index.html.twig
So you want store "{{ store }}"? 
13. Model
- define a model  store/category
- Store model
- vi ASF/StoreBundle/Entity/Store.php 
<?php
// ASF/storeBundle/Entity/Store.php
namespace ASF\StoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 */
class Store
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
     protected $id;
    /**
     * @ORM\ManyToMany(targetEntity="Category")
     * @ORM\JoinTable(name="stores_categories",
     *      joinColumns={@ORM\JoinColumn(name="store_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")})
     */
    protected $categories;
    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $url;
    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $name;
    /**
     * @ORM\Column(type="integer")
     */
    protected $clicks = 0;
    /**
     * @ORM\Column(type="boolean")
     */
    protected $validated = false;
    /**
     * @ORM\Column(type="integer")
     */
    protected $pcomments = 0;
    /**
     * @ORM\Column(type="integer")
     */
    protected $ncomments = 0;
    /**
     * @ORM\Column(type="boolean")
     */
    protected $active = false;
    /**
     * @ORM\Column(type="datetime", name="updated_at")
     */
    protected $updatedAt;
    /**
     * @ORM\Column(type="datetime", name="created_at")
     */
    protected $createdAt;
    public function __construct()
    {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
        $this->createdAt = new \DateTime();
        $this->updatedAt = new \DateTime();
    }
}
- Store model
- vi ASF/StoreBundle/Entity/Category.php



<?php
// ASF/StoreBundle/Entity/Category.php
namespace ASF\StoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     */
    protected $children;
    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     * @ORM\Column(nullable=true)
     */
    protected $parent;
    /**
     * @ORM\ManyToMany(targetEntity="Store", mappedBy="categories")
     */
    protected $stores;
    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $name;
    /**
     * @ORM\Column(type="string", length=255, name="url_string", unique=true)
     */
    protected $urlString;
    public function __construct()
    {
        $this->stores = new \Doctrine\Commmon\Collections\ArrayCollection();
    }
}
Creating Tables :
php app/console doctrine:schema:create
Creating Getters & Setters
php app/console doctrine:generate:entities ASFStoreBundle
 14. Test the module
add to the routing the storeAction:
vi src/ASF/StoreBundle/Resources/config/routing.yml

asf_mystore:
    pattern:  /store/{store}
    defaults: { _controller: ASFStoreBundle:Store:store }
asf_mystore_index:
    pattern:  /store/
    defaults: { _controller: ASFStoreBundle:Store:index }


vi src/ASF/StoreBundle/Controller/StoreController.php

<?php
//ASF/StoreBundle/Controller/StoreController.php
namespace ASF\StoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;





class StoreController extends Controller
{

    /**
     * @Template()
     */
    public function indexAction()
    {
        $em = $this->get('doctrine.orm.entity_manager');
        $stores = $em->createQuery('SELECT count(s.id) AS total FROM ASF\StoreBundle\Entity\Store s')->getSingleScalarResult();
        return array('stores' => $stores);
    }

    /**
     * @Template()
     */
    public function storeAction($store)
    {
        return array('store' => $store);
    }
}

vi src/ASF/StoreBundle/Resources/views/Store/index.html.twig
<!-- Montes/AdictosBundle/Resources/views/Store/index.html.twig -->
We have a total of {{ stores }} stores.



vi src/ASF/StoreBundle/Resources/views/Store/store.html.twig

<!-- Montes/AdictosBundle/Resources/views/Store/store.html.twig -->
So you want store "{{ store }}"?
 
 

Thursday, August 15, 2013

Making a framework on top of symfony2

Summary from http://fabien.potencier.org/article/51/create-your-own-framework-on-top-of-the-symfony2-components-part-1 -12
 
 
$ mkdir framework
$ cd framework 
 
$ vi composer.json
   
{
    "require": {
        "symfony/class-loader": "2.1.*"
    }
}
 
:wq
 
$ wget http://getcomposer.org/composer.phar
$ # or
$ curl -O http://getcomposer.org/composer.phar
$ php composer.phar install
 
$ vi autoload.php
<?php
 
// framework/autoload.php
 
require_once __DIR__.'/vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php';
 
use Symfony\Component\ClassLoader\UniversalClassLoader;
 
$loader = new UniversalClassLoader();
$loader->register();
 
:wq
 
$ php autoload.php 
 
$ vi index.php  (error version if no get parameter supply)
<?php
// framework/index.php
$input = $_GET['name'];
printf('Hello %s', $input);
:wq
 
=> go to http://localhost and it will show hello

$ vi index.php  (unsecure version : Internet security issue, XSS (Cross-Site Scripting))
 
 <?php
 
// framework/index.php
 
$input = isset($_GET['name']) ? $_GET['name'] : 'World';
 
printf('Hello %s', $input);
:wq
 

$vi index.php (secure versinon)

<?php
$input = isset($_GET['name']) ? $_GET['name'] : 'World';
header('Content-Type: text/html; charset=utf-8');
printf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8'))
:wq 
 

==>test unit

vi test.php
<?php
 
// framework/test.php
 
class IndexTest extends \PHPUnit_Framework_TestCase
{
    public function testHello()
    {
        $_GET['name'] = 'Fabien';
 
        ob_start();
        include 'index.php';
        $content = ob_get_clean();
 
        $this->assertEquals('Hello Fabien', $content);
    }
}
:wq
 
=> At this point, if you are not convinced that security and testing are indeed
two very good reasons to stop writing code the old way and adopt a framework
instead 
 
 In PHP, the request is represented by global variables ($_GET, $_POST,
$_FILE, $_COOKIE, $_SESSION...) and the response is generated by
functions (echo, header, setcookie, ...).
 
=>better code : Object-Oriented approach, Symfony2 HttpFoundation component
 

$ vi framework/composer.json
{
    "require": {
        "symfony/class-loader": "2.1.*",
        "symfony/http-foundation": "2.1.*"
    }
}

:wq

php composer.phar update

vi autoload.php add at bootom :
 
<?php
 
// framework/autoload.php
 
$loader->registerNamespace('Symfony\\Component\\HttpFoundation', __DIR__.'/vendor/symfony/http-foundation')
 
wq:  
 
$ vi index.php

<?php
 
// framework/index.php
 
require_once __DIR__.'/autoload.php';
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
 
$request = Request::createFromGlobals();
$input = $request->get('name', 'World');
$response = new Response(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));
$response->send();
 
:wq 
 
$ vi bye.php
 
<?php
 
// framework/bye.php
 
require_once __DIR__.'/autoload.php';
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
 
$request = Request::createFromGlobals();
 
$response = new Response('Goodbye!');
$response->send();
:wq
 
$ vi init.php
<?php
 
// framework/init.php
 
require_once __DIR__.'/autoload.php';
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
 
$request = Request::createFromGlobals();
$response = new Response();
 
:wq
 
$ vi index.php<?php
 
// framework/index.php
 
require_once __DIR__.'/init.php';
 
$input = $request->get('name', 'World');
 
$response->setContent(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));
$response->send();
wq
 
$ vi bye.php
<?php
 
// framework/bye.php
 
require_once __DIR__.'/init.php';
 
$response->setContent('Goodbye!');
$response->send();
 
:wq
 
$ vi front.php
<?php
 
// framework/front.php
 
require_once __DIR__.'/autoload.php';
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
 
$request = Request::createFromGlobals();
$response = new Response();
 
$map = array(
    '/hello' => __DIR__.'/hello.php',
    '/bye'   => __DIR__.'/bye.php',
);
 
$path = $request->getPathInfo();
if (isset($map[$path])) {
    require $map[$path];
} else {
    $response->setStatusCode(404);
    $response->setContent('Not Found');
}
 
$response->send();
 
:wq
 
$ vi hello.php
<?php
 
// framework/hello.php
 
$input = $request->get('name', 'World');
$response->setContent(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));
 
:wq

==> http://example.com/front.php/hello?name=Fabien
==> http://example.com/front.php/bye
 
  
Now that the web server always access the same script (front.php) for all our pages, we can secure our code further by moving all other PHP files outside the web root directory:
example.com
??? composer.json
?        src
?        ??? autoload.php
?        ??? pages
?        ??? hello.php
?        ??? bye.php
??? vendor
??? web
??? front.php  

Now, configure your web server root directory to point to web/ and all other files won't be accessible from the client anymore.

vi src/pages/hello.php

<!-- example.com/src/pages/hello.php -->
 
<?php $name = $request->get('name', 'World') ?>
 
Hello <?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>
 
:wq
 
$ vi web/front.php
 <?php
 
// example.com/web/front.php
 
require_once __DIR__.'/../src/autoload.php';
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
 
$request = Request::createFromGlobals();
$response = new Response();
 
$map = array(
    '/hello' => __DIR__.'/../src/pages/hello.php',
    '/bye'   => __DIR__.'/../src/pages/bye.php',
);
 
$path = $request->getPathInfo();
if (isset($map[$path])) {
    ob_start();
    include $map[$path];
    $response->setContent(ob_get_clean());
} else {
    $response->setStatusCode(404);
    $response->setContent('Not Found');
}
 
$response->send();
 
:wq

 
.
.
.
.
.
.
.
.
.
That's it! Our application has now four different layers and each of them has a well defined goal:
  • web/front.php: The front controller; the only exposed PHP code that makes the interface with the client (it gets the Request and sends the Response) and provides the boiler-plate code to initialize the framework and our application;
  • src/Simplex: The reusable framework code that abstracts the handling of incoming Requests (by the way, it makes your controllers/templates easily testable -- more about that later on);
  • src/Calendar: Our application specific code (the controllers and the model);
  • src/app.php: The application configuration/framework customization.