Bladeren bron

Refactor of controllers, and app boot see #7124

Adding breadcrumb support using the knp-menu lib.
Simplifying CRUD classes creations see example in RoleController.
Defining group of controller Admin, App (global apps), Tool (course tools),
and User (social profile).
Moving template.lib.php into Framework\Template.php
Improving ReflectionControllerProvider (to use more than one route, methods and aliases).
Splitting code from global.inc.php into:
app.php (start process), filters.php (filters/middleware), paths.php, routes.php and services.php.
Julio Montoya 10 jaren geleden
bovenliggende
commit
92eb1e6165
83 gewijzigde bestanden met toevoegingen van 2252 en 2319 verwijderingen
  1. 12 5
      main/inc/lib/course_home.lib.php
  2. 1 1
      main/inc/lib/database.constants.inc.php
  3. 3 3
      main/inc/lib/display.lib.php
  4. 1 4
      src/ChamiloLMS/Component/Editor/CkEditor/Toolbar/Documents.php
  5. 6 8
      src/ChamiloLMS/Controller/Admin/AdminController.php
  6. 36 70
      src/ChamiloLMS/Controller/Admin/Administrator/BranchController.php
  7. 24 73
      src/ChamiloLMS/Controller/Admin/Administrator/JuryController.php
  8. 25 83
      src/ChamiloLMS/Controller/Admin/Administrator/QuestionScoreController.php
  9. 11 78
      src/ChamiloLMS/Controller/Admin/Administrator/QuestionScoreNameController.php
  10. 14 76
      src/ChamiloLMS/Controller/Admin/Administrator/RoleController.php
  11. 6 14
      src/ChamiloLMS/Controller/Admin/Administrator/UpgradeController.php
  12. 25 35
      src/ChamiloLMS/Controller/Admin/Director/BranchDirectorController.php
  13. 30 41
      src/ChamiloLMS/Controller/Admin/JuryMember/JuryMemberController.php
  14. 26 39
      src/ChamiloLMS/Controller/Admin/JuryPresident/JuryPresidentController.php
  15. 121 105
      src/ChamiloLMS/Controller/Admin/QuestionManager/QuestionManagerController.php
  16. 3 2
      src/ChamiloLMS/Controller/App/Certificate/CertificateController.php
  17. 3 2
      src/ChamiloLMS/Controller/App/Editor/EditorController.php
  18. 1 1
      src/ChamiloLMS/Controller/App/ModelAjax/ModelAjaxController.php
  19. 29 20
      src/ChamiloLMS/Controller/App/News/NewsController.php
  20. 23 44
      src/ChamiloLMS/Controller/App/SessionPath/SessionPathController.php
  21. 13 35
      src/ChamiloLMS/Controller/App/SessionPath/SessionTreeController.php
  22. 364 366
      src/ChamiloLMS/Controller/BaseController.php
  23. 0 155
      src/ChamiloLMS/Controller/CommonController.php
  24. 0 18
      src/ChamiloLMS/Controller/CourseCommonController.php
  25. 496 0
      src/ChamiloLMS/Controller/CrudController.php
  26. 37 0
      src/ChamiloLMS/Controller/CrudControllerInterface.php
  27. 125 83
      src/ChamiloLMS/Controller/IndexController.php
  28. 15 13
      src/ChamiloLMS/Controller/LegacyController.php
  29. 0 1
      src/ChamiloLMS/Controller/Tool/CourseController.php
  30. 42 63
      src/ChamiloLMS/Controller/Tool/CourseHome/CourseHomeController.php
  31. 39 50
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumCategoryController.php
  32. 2 2
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumController.php
  33. 33 67
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumItemController.php
  34. 41 86
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumUserController.php
  35. 3 2
      src/ChamiloLMS/Controller/Tool/Exercise/ExerciseController.php
  36. 29 23
      src/ChamiloLMS/Controller/Tool/Introduction/IntroductionController.php
  37. 4 3
      src/ChamiloLMS/Controller/Tool/LearningPath/LearningPathController.php
  38. 185 0
      src/ChamiloLMS/Controller/ToolBaseController.php
  39. 3 3
      src/ChamiloLMS/Controller/User/ProfileController.php
  40. 3 3
      src/ChamiloLMS/Controller/User/UserController.php
  41. 0 116
      src/ChamiloLMS/Controller/UserPortalController.php
  42. 1 1
      src/ChamiloLMS/Form/BranchType.php
  43. 1 1
      src/ChamiloLMS/Form/CourseHomeToolType.php
  44. 1 1
      src/ChamiloLMS/Form/CurriculumCategoryType.php
  45. 1 1
      src/ChamiloLMS/Form/CurriculumItemRelUserCollectionType.php
  46. 1 1
      src/ChamiloLMS/Form/CurriculumItemRelUserType.php
  47. 1 1
      src/ChamiloLMS/Form/JuryMembersType.php
  48. 1 1
      src/ChamiloLMS/Form/JuryType.php
  49. 1 1
      src/ChamiloLMS/Form/JuryUserType.php
  50. 1 1
      src/ChamiloLMS/Form/QuestionScoreNameType.php
  51. 1 1
      src/ChamiloLMS/Form/QuestionScoreType.php
  52. 1 1
      src/ChamiloLMS/Form/RoleType.php
  53. 1 1
      src/ChamiloLMS/Form/SessionPathType.php
  54. 1 1
      src/ChamiloLMS/Form/SessionTreeType.php
  55. 4 1
      src/ChamiloLMS/Framework/Application.php
  56. 8 13
      src/ChamiloLMS/Framework/PageController.php
  57. 52 28
      src/ChamiloLMS/Framework/Template.php
  58. 14 0
      src/ChamiloLMS/Framework/Widget.php
  59. 51 5
      src/ChamiloLMS/Provider/ReflectionControllerProvider.php
  60. 2 2
      src/ChamiloLMS/Resources/views/default/admin/administrator/branches/list.tpl
  61. 2 2
      src/ChamiloLMS/Resources/views/default/admin/administrator/role/list.tpl
  62. 1 0
      src/ChamiloLMS/Resources/views/default/admin/index.tpl
  63. 0 0
      src/ChamiloLMS/Resources/views/default/admin/question_manager/edit_category.tpl
  64. 0 0
      src/ChamiloLMS/Resources/views/default/admin/question_manager/edit_question.tpl
  65. 2 2
      src/ChamiloLMS/Resources/views/default/admin/question_manager/question_categories.tpl
  66. 1 1
      src/ChamiloLMS/Resources/views/default/admin/question_manager/questionmanager.tpl
  67. 2 2
      src/ChamiloLMS/Resources/views/default/admin/question_manager/questions.tpl
  68. 21 0
      src/ChamiloLMS/Resources/views/default/admin/question_manager/role_index.tpl
  69. 0 0
      src/ChamiloLMS/Resources/views/default/admin/question_manager/show_category.tpl
  70. 0 13
      src/ChamiloLMS/Resources/views/default/admin/questionmanager/role_index.tpl
  71. 30 17
      src/ChamiloLMS/Resources/views/default/crud_macros/simple_crud.tpl
  72. 2 1
      src/ChamiloLMS/Resources/views/default/layout/bread.tpl
  73. 18 20
      src/ChamiloLMS/Resources/views/default/layout/breadcrumb.tpl
  74. 1 1
      src/ChamiloLMS/Resources/views/default/layout/menu.tpl
  75. 3 17
      src/ChamiloLMS/Resources/views/default/layout/sidebar.tpl
  76. 0 8
      src/ChamiloLMS/Resources/views/default/pages/add.tpl
  77. 0 14
      src/ChamiloLMS/Resources/views/default/pages/listing.tpl
  78. 0 8
      src/ChamiloLMS/Resources/views/default/pages/show.tpl
  79. 8 26
      src/ChamiloLMS/app.php
  80. 5 3
      src/ChamiloLMS/filters.php
  81. 1 0
      src/ChamiloLMS/paths.php
  82. 52 169
      src/ChamiloLMS/routes.php
  83. 125 160
      src/ChamiloLMS/services.php

+ 12 - 5
main/inc/lib/course_home.lib.php

@@ -673,7 +673,10 @@ class CourseHome
                             if (!empty($tool['id'])) {
                                 $link['cmd'] = $urlGenerator->generate(
                                     'course_home.controller:hideIconAction',
-                                    array('course' => api_get_course_id(), 'iconId' => $tool['id'])
+                                    array(
+                                        'courseCode' => api_get_course_id(),
+                                        'iconId' => $tool['id']
+                                    )
                                 );
                             }
                             $lnk[] = $link;
@@ -683,7 +686,10 @@ class CourseHome
                             if (!empty($tool['id'])) {
                                 $link['cmd'] = $urlGenerator->generate(
                                     'course_home.controller:showIconAction',
-                                    array('course' => api_get_course_id(), 'iconId' => $tool['id'])
+                                    array(
+                                        'courseCode' => api_get_course_id(),
+                                        'iconId' => $tool['id']
+                                    )
                                 );
                             }
                             $lnk[] = $link;
@@ -691,7 +697,8 @@ class CourseHome
                     }
 
                     if (!empty($tool['adminlink'])) {
-                        $item['extra'] = '<a href="'.$tool['adminlink'].'">'.Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
+                        $item['extra'] = '<a href="'.$tool['adminlink'].'">'.
+                            Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
                     }
                 }
 
@@ -755,7 +762,7 @@ class CourseHome
                         'id'      => 'tooldesc_'.$tool["id"],
                         'href'    => '"javascript: void(0);"',
                         'class'   => $class,
-                        'onclick' => 'javascript: window.open(\'' . $tool['link'] . '\',\'window_visio'.$_SESSION['_cid'].'\',config=\'height=\'+730+\', width=\'+1020+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')',
+                        'onclick' => 'javascript: window.open(\'' . $tool['link'] . '\',\'window_visio'.api_get_course_id().'\',config=\'height=\'+730+\', width=\'+1020+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')',
                         'target'  =>  $tool['target']
                     );
                 } elseif (strpos($tool['name'], 'chat') !== false && api_get_course_setting('allow_open_chat_window')) {
@@ -763,7 +770,7 @@ class CourseHome
                         'id'      => 'tooldesc_'.$tool["id"],
                         'class'   => $class,
                         'href'    => 'javascript: void(0);',
-                        'onclick' => 'javascript: window.open(\'' . $tool['link'] . '\',\'window_chat'.$_SESSION['_cid'].'\',config=\'height=\'+380+\', width=\'+625+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')',
+                        'onclick' => 'javascript: window.open(\'' . $tool['link'] . '\',\'window_chat'.api_get_course_id().'\',config=\'height=\'+380+\', width=\'+625+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')',
                         'target'  =>  $tool['target']
                     );
                 } else {

+ 1 - 1
main/inc/lib/database.constants.inc.php

@@ -5,7 +5,7 @@
  *  This file is called by database.lib.php and database.mysqli.lib.php
  *
  *  @todo the table constants have all to start with TABLE_
- *        This is because of the analogy with the tool constants TOOL_
+ *  This is because of the analogy with the tool constants TOOL_
  *
  *	@package chamilo.library
  */

+ 3 - 3
main/inc/lib/display.lib.php

@@ -214,7 +214,7 @@ class Display
 
                     $url = $urlGenerator->generate(
                         'introduction.controller:editAction',
-                        array('tool' => $tool, 'course' => api_get_course_id())
+                        array('tool' => $tool, 'courseCode' => api_get_course_id())
                     );
 
                     $introduction_section .=  "<a href=\"".$url."?".api_get_cidreq()."\">";
@@ -228,7 +228,7 @@ class Display
                     $introduction_section .=  '<div id="introduction_block_action" class="col-md-2 col-md-offset-10">';
                     $url = $urlGenerator->generate(
                         'introduction.controller:editAction',
-                        array('tool' => $tool, 'course' => api_get_course_id())
+                        array('tool' => $tool, 'courseCode' => api_get_course_id())
                     );
 
                     $introduction_section .=  "<a href=\"".$url."?".api_get_cidreq()."\">";
@@ -237,7 +237,7 @@ class Display
 
                     $url = $urlGenerator->generate(
                         'introduction.controller:deleteAction',
-                        array('tool' => $tool, 'course' => api_get_course_id())
+                        array('tool' => $tool, 'courseCode' => api_get_course_id())
                     );
 
                     $introduction_section .=  "<a onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('ConfirmYourChoice')))."')) return false;\" href=\"".$url."?".api_get_cidreq()."\">";

+ 1 - 4
src/ChamiloLMS/Component/Editor/CkEditor/Toolbar/Documents.php

@@ -30,10 +30,7 @@ class Documents extends Basic
         );
 
         $config['extraPlugins'] = $this->getConfigAttribute('extraPlugins').',mathjax';
-        $config['mathJaxLib'] = $this->urlGenerator->generate(
-            'legacy.controller:getJavascript',
-            array('file' => 'math_jax/MathJax.js', 'config'=> 'default')
-        );
+        $config['mathJaxLib'] = $this->urlGenerator->generate('javascript').'/math_jax/MathJax.js?config=default';
         $config['fullPage'] = true;
         return $config;
     }

+ 6 - 8
src/ChamiloLMS/Controller/Admin/AdminController.php

@@ -3,14 +3,12 @@
 
 namespace ChamiloLMS\Controller\Admin;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
+use Entity;
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
-use Entity;
-use ChamiloLMS\Form\QuestionScoreType;
 
 /**
  * Class Administrator
@@ -18,19 +16,18 @@ use ChamiloLMS\Form\QuestionScoreType;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class AdminController extends CommonController
+class AdminController extends BaseController
 {
     /**
-     *
      * @Route("/")
      * @Method({"GET"})
+     *
      * @return Response
      */
     public function indexAction()
     {
         $template = $this->getTemplate();
-        /** @var  \Symfony\Component\Security\Core\SecurityContext  $security */
-        $security = $this->get('security');
+        $security = $this->getSecurity();
 
         if (!$security->isGranted($this->app['allow_admin_toolbar'])) {
             return $this->abort(403, 'Access denied');
@@ -40,6 +37,7 @@ class AdminController extends CommonController
             $this->loadAdminMenu();
         }
         $response = $template->renderTemplate('admin/index.tpl');
+
         return new Response($response, 200, array());
     }
 

+ 36 - 70
src/ChamiloLMS/Controller/Admin/Administrator/BranchController.php

@@ -3,9 +3,8 @@
 
 namespace ChamiloLMS\Controller\Admin\Administrator;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
 use Entity;
@@ -19,12 +18,34 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * Class RoleController
- * @todo @route and @method function don't work yet
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Admin\Administrator
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class BranchController extends CommonController
+class BranchController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\BranchSync';
+    }
+
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\BranchType';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'branch.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'admin/administrator/branches/';
+    }
+
     /**
      * @Route("/")
      * @Method({"GET"})
@@ -63,7 +84,8 @@ class BranchController extends CommonController
         $htmlTree = $repo->buildTree($query->getArrayResult(), $options);
         $this->get('template')->assign('tree', $htmlTree);
         $this->get('template')->assign('links', $this->generateLinks());
-        $response = $this->get('template')->render_template($this->getTemplatePath().'list.tpl');
+        $response = $this->renderTemplate('list.tpl');
+
         return new Response($response, 200, array());
     }
 
@@ -114,7 +136,7 @@ class BranchController extends CommonController
         $template = $this->get('template');
         $template->assign('form', $form->createView());
         $template->assign('id', $id);
-        $response = $template->render_template($this->getTemplatePath().'add_director.tpl');
+        $response = $this->renderTemplate('add_director.tpl');
         return new Response($response, 200, array());
     }
 
@@ -159,19 +181,10 @@ class BranchController extends CommonController
         $children = $repo->children($item);
         $template->assign('item', $item);
         $template->assign('subitems', $children);
-        $response = $template->render_template($this->getTemplatePath().'read.tpl');
+        $response = $this->renderTemplate('read.tpl');
         return new Response($response, 200, array());
     }
 
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
-
     /**
     * @Route("/{id}/add")
     * @Method({"GET, POST"})
@@ -207,21 +220,11 @@ class BranchController extends CommonController
         $template->assign('links', $this->generateLinks());
         $template->assign('form', $form->createView());
         $template->assign('parent_id', $id);
-        $response = $template->render_template($this->getTemplatePath().'add_from_parent.tpl');
+        $response = $this->renderTemplate('add_from_parent.tpl');
 
         return new Response($response, 200, array());
     }
 
-    /**
-    *
-    * @Route("/{id}/edit", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function editAction($id)
-    {
-        return parent::editAction($id);
-    }
-
     /**
     *
     * @Route("/{id}/delete", requirements={"id" = "\d+"})
@@ -236,9 +239,11 @@ class BranchController extends CommonController
         if (count($children) == 0) {
             return parent::deleteAction($id);
         } else {
-            $this->get('session')->getFlashBag()->
-                add('warning', "Please remove all children of this node before you try to delete it.");
-            $url = $this->createUrl('list_link');
+            $this->addMessage(
+                'Please remove all children of this node before you try to delete it.',
+                'warning'
+            );
+            $url = $this->generateControllerUrl('listingAction');
             return $this->redirect($url);
         }
     }
@@ -276,7 +281,6 @@ class BranchController extends CommonController
         $request = $this->getRequest();
         $id = $request->get('id');
         $item = $this->getEntity($id);
-        $repo = $this->getRepository();
         $result = 0;
         if ($item) {
             $result  = 1;
@@ -284,48 +288,10 @@ class BranchController extends CommonController
         return new Response($result, 200, array());
     }
 
-    protected function getControllerAlias()
-    {
-        return 'branch.controller';
-    }
-
     protected function generateDefaultCrudRoutes()
     {
         $routes = parent::generateDefaultCrudRoutes();
         $routes['add_from_parent_link'] = 'branch.controller:addFromParentAction';
         return $routes ;
     }
-
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/administrator/branches/';
-    }
-
-    /**
-     * @return \ChamiloLMS\Entity\Repository\BranchSyncRepository
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\BranchSync');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new BranchSync();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new BranchType();
-    }
 }

+ 24 - 73
src/ChamiloLMS/Controller/Admin/Administrator/JuryController.php

@@ -3,8 +3,7 @@
 
 namespace ChamiloLMS\Controller\Admin\Administrator;
 
-use ChamiloLMS\Controller\CommonController;
-use Silex\Application;
+use ChamiloLMS\Controller\CrudController;
 use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
 use Entity;
@@ -20,20 +19,35 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * Class JuryController
- * @todo @route and @method function don't work yet
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Admin\Administrator
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class JuryController extends CommonController
+class JuryController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\Jury';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'jury.controller';
+    }
+
     /**
-     *
-     * @Route("/")
-     * @Method({"GET"})
+     * {@inheritdoc}
      */
-    public function indexAction()
+    public function getType()
     {
-        return parent::listingAction();
+        return 'ChamiloLMS\Form\JuryType';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'admin/administrator/juries/';
     }
 
     /**
@@ -53,34 +67,6 @@ class JuryController extends CommonController
         return new Response($response, 200, array());
     }
 
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
-
-    /**
-    *
-    * @Route("/{id}/edit", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function editAction($id)
-    {
-        return parent::editAction($id);
-    }
-
-    /**
-    * @Route("/{id}/delete", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function deleteAction($id)
-    {
-        return parent::deleteAction($id);
-    }
-
      /**
     * @Route("/{id}/remove-member", requirements={"id" = "\d+"})
     * @Method({"GET"})
@@ -188,40 +174,5 @@ class JuryController extends CommonController
         return $routes ;
     }
 
-    protected function getControllerAlias()
-    {
-        return 'jury.controller';
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/administrator/juries/';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\Jury');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new Jury();
-    }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new JuryType();
-    }
 }

+ 25 - 83
src/ChamiloLMS/Controller/Admin/Administrator/QuestionScoreController.php

@@ -3,31 +3,43 @@
 
 namespace ChamiloLMS\Controller\Admin\Administrator;
 
-use ChamiloLMS\Controller\CommonController;
-use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
+use ChamiloLMS\Controller\CrudController;
 use Symfony\Component\HttpFoundation\Response;
+use ChamiloLMS\Entity;
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
-use ChamiloLMS\Entity;
-use ChamiloLMS\Form\QuestionScoreType;
-use ChamiloLMS\Entity\QuestionScore;
 
 /**
  * Class QuestionScoreController
- * @todo @route and @method function don't work yet
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Admin\Administrator
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class QuestionScoreController extends CommonController
+class QuestionScoreController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\BranchSync';
+    }
+
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\QuestionScoreType';
+    }
+
     /**
-     * @Route("/")
-     * @Method({"GET"})
+     * {@inheritdoc}
      */
-    public function indexAction()
+    public function getControllerAlias()
     {
-        return parent::listingAction();
+        return 'question_score.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'admin/administrator/question_score/';
     }
 
     /**
@@ -37,7 +49,6 @@ class QuestionScoreController extends CommonController
     */
     public function readAction($id)
     {
-        // return parent::readAction($id);
         $template = $this->get('template');
         $template->assign('links', $this->generateLinks());
         $item = $this->getEntity($id);
@@ -49,79 +60,10 @@ class QuestionScoreController extends CommonController
         return new Response($response, 200, array());
     }
 
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
-
-    /**
-    *
-    * @Route("/{id}/edit", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function editAction($id)
-    {
-        return parent::editAction($id);
-    }
-
-    /**
-    *
-    * @Route("/{id}/delete", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function deleteAction($id)
-    {
-        return parent::deleteAction($id);
-    }
-
     protected function generateDefaultCrudRoutes()
     {
         $routes = parent::generateDefaultCrudRoutes();
         $routes['question_score_name_read_link'] = 'question_score_name.controller:readAction';
         return $routes ;
     }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getControllerAlias()
-    {
-        return 'question_score.controller';
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\QuestionScore');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new QuestionScore();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new QuestionScoreType();
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/administrator/question_score/';
-    }
 }

+ 11 - 78
src/ChamiloLMS/Controller/Admin/Administrator/QuestionScoreNameController.php

@@ -3,73 +3,29 @@
 
 namespace ChamiloLMS\Controller\Admin\Administrator;
 
-use ChamiloLMS\Controller\CommonController;
-use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\Routing\Annotation\Route;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+use ChamiloLMS\Controller\CrudController;
 use ChamiloLMS\Entity;
-use ChamiloLMS\Form\QuestionScoreNameType;
-use ChamiloLMS\Entity\QuestionScoreName;
 
 /**
  * Class QuestionScoreController
  * @todo @route and @method function don't work yet
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Admin\Administrator
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class QuestionScoreNameController extends CommonController
-{
-    /**
-     * @Route("/")
-     * @Method({"GET"})
-     */
-    public function indexAction()
-    {
-        return parent::listingAction();
-    }
-
-    /**
-    *
-    * @Route("/{id}", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function readAction($id)
-    {
-        return parent::readAction($id);
-    }
-
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
 
-    /**
-    *
-    * @Route("/{id}/edit", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function editAction($id)
+class QuestionScoreNameController extends CrudController
+{
+    public function getClass()
     {
-        return parent::editAction($id);
+        return 'ChamiloLMS\Entity\QuestionScoreName';
     }
 
-    /**
-    *
-    * @Route("/{id}/delete", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function deleteAction($id)
+    public function getType()
     {
-        return parent::deleteAction($id);
+        return 'ChamiloLMS\Form\QuestionScoreNameType';
     }
 
-    protected function getControllerAlias()
+    public function getControllerAlias()
     {
         return 'question_score_name.controller';
     }
@@ -77,32 +33,9 @@ class QuestionScoreNameController extends CommonController
     /**
      * {@inheritdoc}
      */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\QuestionScoreName');
-    }
-
-     /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new QuestionScoreName();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new QuestionScoreNameType();
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
+    public function getTemplatePath()
     {
         return 'admin/administrator/question_score_name/';
     }
 }
+

+ 14 - 76
src/ChamiloLMS/Controller/Admin/Administrator/RoleController.php

@@ -3,107 +3,45 @@
 
 namespace ChamiloLMS\Controller\Admin\Administrator;
 
-use ChamiloLMS\Controller\CommonController;
-use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
-use Symfony\Component\HttpFoundation\Response;
+use ChamiloLMS\Controller\CrudController;
 use ChamiloLMS\Entity;
-use ChamiloLMS\Form\RoleType;
-use ChamiloLMS\Entity\Role;
-use Symfony\Component\Routing\Annotation\Route;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * Class RoleController
- * @todo @route and @method function don't work yet
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Admin\Administrator
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class RoleController extends CommonController
+class RoleController extends CrudController
 {
     /**
-     *
-     * @Route("/")
-     * @Method({"GET"})
+     * {@inheritdoc}
      */
-    public function indexAction()
-    {
-        return parent::listingAction();
-    }
-
-    /**
-    *
-    * @Route("/{id}", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function readAction($id)
-    {
-        return parent::readAction($id);
-    }
-
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
-
-    /**
-    *
-    * @Route("/{id}/edit", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function editAction($id)
-    {
-        return parent::editAction($id);
-    }
-
-    /**
-    *
-    * @Route("/{id}/delete", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function deleteAction($id)
-    {
-        return parent::deleteAction($id);
-    }
-
-    protected function getControllerAlias()
+    public function getClass()
     {
-        return 'role.controller';
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/administrator/role/';
+        return 'ChamiloLMS\Entity\Role';
     }
 
     /**
      * {@inheritdoc}
      */
-    protected function getRepository()
+    public function getType()
     {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\Role');
+        return 'ChamiloLMS\Form\RoleType';
     }
 
     /**
      * {@inheritdoc}
      */
-    protected function getNewEntity()
+    /*public function getControllerAlias()
     {
-        return new Role();
-    }
+        return 'role.controller';
+    }*/
 
     /**
      * {@inheritdoc}
      */
-    protected function getFormType()
+    /*public function getTemplatePath()
     {
-        return new RoleType();
-    }
+        return 'admin/administrator/role/';
+    }*/
 }

+ 6 - 14
src/ChamiloLMS/Controller/Admin/Administrator/UpgradeController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\Admin\Administrator;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\Form\Extension\Core\Type\FormType;
 use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
@@ -20,7 +20,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class UpgradeController extends CommonController
+class UpgradeController extends BaseController
 {
     /**
      * @Route("/")
@@ -29,7 +29,7 @@ class UpgradeController extends CommonController
     public function indexAction()
     {
         //$version = api_http_request('version.chamilo.org', 80, '/version.php');
-        $version = '1.11.0';
+        $version = '11';
 
         $request = $this->getRequest();
         $builder = $this->createFormBuilder();
@@ -180,24 +180,16 @@ class UpgradeController extends CommonController
         return new Response($response, 200, array());
     }
 
-    protected function getControllerAlias()
+    /*protected function getControllerAlias()
     {
         return 'upgrade.controller';
-    }
+    }*/
 
     /**
     * {@inheritdoc}
     */
-    protected function getTemplatePath()
+    public function getTemplatePath()
     {
         return 'admin/administrator/upgrade/';
     }
-
-    /**
-     * @return \ChamiloLMS\Entity\Repository\BranchSyncRepository
-     */
-    protected function getRepository()
-    {
-
-    }
 }

+ 25 - 35
src/ChamiloLMS/Controller/Admin/Director/BranchDirectorController.php

@@ -3,8 +3,7 @@
 
 namespace ChamiloLMS\Controller\Admin\Director;
 
-use ChamiloLMS\Controller\CommonController;
-use ChamiloLMS\Form\BranchType;
+use ChamiloLMS\Controller\CrudController;
 use ChamiloLMS\Form\DirectorJuryUserType;
 use ChamiloLMS\Form\JuryType;
 use ChamiloLMS\Entity;
@@ -13,10 +12,7 @@ use ChamiloLMS\Entity\Jury;
 use ChamiloLMS\Entity\User;
 use ChamiloLMS\Entity\JuryMembers;
 use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\Routing\Annotation\Route;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * Class RoleController
@@ -24,8 +20,31 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class BranchDirectorController extends CommonController
+class BranchDirectorController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\BranchSync';
+    }
+
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\DirectorJuryUserType';
+    }
+
+    protected function getControllerAlias()
+    {
+        return 'branch_director.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getTemplatePath()
+    {
+        return 'admin/director/branches/';
+    }
+
     /**
      * @Route("/")
      * @Method({"GET"})
@@ -189,33 +208,4 @@ class BranchDirectorController extends CommonController
     {
 
     }
-
-    protected function getControllerAlias()
-    {
-        return 'branch_director.controller';
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/director/branches/';
-    }
-
-    /**
-     * @return \ChamiloLMS\Entity\Repository\BranchSyncRepository
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\BranchSync');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new BranchSync();
-    }
 }

+ 30 - 41
src/ChamiloLMS/Controller/Admin/JuryMember/JuryMemberController.php

@@ -3,15 +3,13 @@
 
 namespace ChamiloLMS\Controller\Admin\JuryMember;
 
-use ChamiloLMS\Controller\CommonController;
-use ChamiloLMS\Form\JuryType;
+use ChamiloLMS\Controller\CrudController;
 use ChamiloLMS\Entity\TrackExercise;
 use ChamiloLMS\Entity\Jury;
 use ChamiloLMS\Entity\TrackExerciseAttemptJury;
 use ChamiloLMS\Entity\JuryMembers;
 use ChamiloLMS\Entity;
 use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
 use Doctrine\Common\Collections\Criteria;
 use Symfony\Component\Routing\Annotation\Route;
@@ -22,10 +20,37 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class JuryMemberController extends CommonController
+class JuryMemberController extends CrudController
 {
     public $maxCountOfMemberToVoteToConsiderEvaluated = 3;
 
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\Jury';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'jury_member.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'admin/jury_member/';
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\JuryType';
+    }
+
     /**
     * @Route("/")
     * @Method({"GET"})
@@ -159,7 +184,7 @@ class JuryMemberController extends CommonController
             $this->createNotFoundException('You are not assigned to this user.');
         }
 
-        $security = $this->get('security');
+        $security = $this->getSecurity();
 
         // Setting member only for president.
         if ($security->isGranted('ROLE_JURY_PRESIDENT')) {
@@ -379,40 +404,4 @@ class JuryMemberController extends CommonController
 
     }
 
-    protected function getControllerAlias()
-    {
-        return 'jury_member.controller';
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/jury_member/';
-    }
-
-    /**
-     * @return \ChamiloLMS\Entity\Repository\JuryRepository
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\Jury');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new Jury();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new JuryType();
-    }
 }

+ 26 - 39
src/ChamiloLMS/Controller/Admin/JuryPresident/JuryPresidentController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\Admin\JuryPresident;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use ChamiloLMS\Form\JuryType;
 use ChamiloLMS\Form\JuryUserType;
 use ChamiloLMS\Entity\Jury;
@@ -26,9 +26,33 @@ use Whoops\Example\Exception;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class JuryPresidentController extends CommonController
+class JuryPresidentController extends CrudController
 {
     public $maxCountOfMemberToVoteToConsiderEvaluated = 3;
+
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\BranchSync';
+    }
+
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\JuryType';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'jury_president.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'admin/jury_president/';
+    }
+
     /**
     * @Route("/")
     * @Method({"GET"})
@@ -287,41 +311,4 @@ class JuryPresidentController extends CommonController
         $response = $template->render_template($this->getTemplatePath().'check_answers.tpl');
         return new Response($response, 200, array());
     }
-
-    protected function getControllerAlias()
-    {
-        return 'jury_president.controller';
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'admin/jury_president/';
-    }
-
-    /**
-     * @return \ChamiloLMS\Entity\Repository\JuryRepository
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\Jury');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new Jury();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new JuryType();
-    }
 }

+ 121 - 105
src/ChamiloLMS/Controller/Admin/QuestionManager/QuestionManagerController.php

@@ -3,9 +3,11 @@
 
 namespace ChamiloLMS\Controller\Admin\QuestionManager;
 
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
-use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * Class QuestionManagerController
@@ -13,38 +15,45 @@ use Symfony\Component\HttpFoundation\Response;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class QuestionManagerController
+class QuestionManagerController extends BaseController
 {
     /**
-     * @param Application $app
+     * Show the index page for the question manager
+     *
+     * @Route("/")
+     * @Method({"GET"})
+     * @return Response
      */
-    public function indexAction(Application $app)
+    public function indexAction()
     {
+        $response = $this->renderTemplate('questionmanager.tpl');
 
+        return new Response($response, 200, array());
     }
 
     /**
      * Edits a question for the question manager
      *
-     * @param Application $app
+     * @Route("/edit")
+     * @Method({"GET"})
      * @param int $id
      * @return Response
      */
-    public function editQuestionAction(Application $app, $id)
+    public function editQuestionAction($id)
     {
         // Setting exercise obj.
-        $exercise                      = new \Exercise();
+        $exercise = new \Exercise();
         $exercise->edit_exercise_in_lp = true;
 
         // Setting question obj.
         /** @var  \Question $question */
-        $question                   = \Question::read($id, null, $exercise);
-        $question->submitClass      = "btn save";
-        $question->submitText       = get_lang('ModifyQuestion');
+        $question = \Question::read($id, null, $exercise);
+        $question->submitClass = "btn save";
+        $question->submitText = get_lang('ModifyQuestion');
         $question->setDefaultValues = true;
 
         // Generating edit URL.
-        $url = $app['url_generator']->generate('admin_questions_edit', array('id' => $id));
+        $url = $this->generateControllerUrl('editQuestionAction', array('id' => $id));
 
         // Creating a new form
         $form = new \FormValidator('edit_question', 'post', $url);
@@ -55,10 +64,10 @@ class QuestionManagerController
         if (count($form->_elements) > 1) {
             $form->addElement('button', 'submit', get_lang('Update'));
 
-            $app['template']->assign('question', $question);
-            $app['template']->assign('form', $form->toHtml());
+            $this->getTemplate()->assign('question', $question);
+            $this->getTemplate()->assign('form', $form->toHtml());
         } else {
-            $app['template']->assign('message', \Display::return_message(get_lang('ThereAreNotExtrafieldsAvailable'), 'warning'));
+            $this->addMessage(get_lang('ThereAreNotExtrafieldsAvailable'), 'warning');
         }
 
         // If form was submitted.
@@ -67,39 +76,29 @@ class QuestionManagerController
             $params = $form->exportValues();
             $params['question_id'] = $id;
             $field_value->save_field_values($params);
-            $app['template']->assign('message', \Display::return_message(get_lang('ItemUpdated'), 'success'));
-            $url = $app['url_generator']->generate('admin_questions_edit', array('id' => $id));
+            $this->addMessage(get_lang('ItemUpdated'), 'success');
+            $url = $this->generateControllerUrl('editQuestionAction', array('id' => $id));
 
-            return $app->redirect($url);
+            return $this->redirect($url);
         }
 
-        $response = $app['template']->render_template('admin/questionmanager/edit_question.tpl');
-
-        return new Response($response, 200, array());
-    }
-
-    /**
-     * Show the index page for the question manager
-     * @param Application $app
-     * @return Response
-     */
-    public function questionManagerIndexAction(Application $app)
-    {
-        $response = $app['template']->render_template('admin/questionmanager/questionmanager.tpl');
+        $response = $this->renderTemplate('edit_question.tpl');
 
         return new Response($response, 200, array());
     }
 
     /**
      * Get question categories per id
-     * @param Application $app
+     *
+     * @Route("/get_categories")
+     * @Method({"GET"})
      * @param int $id
      * @return string
      */
-    public function getCategoriesAction(Application $app, $id)
+    public function getCategoriesAction($id)
     {
         // Getting CQuizCategory repo.
-        $repo = $app['orm.em']->getRepository('ChamiloLMS\Entity\CQuizCategory');
+        $repo = $this->getManager()->getRepository('ChamiloLMS\Entity\CQuizCategory');
 
         $options  = array(
             'decorate'      => true,
@@ -107,15 +106,22 @@ class QuestionManagerController
             'rootClose'     => '</ul>',
             'childOpen'     => '<li>',
             'childClose'    => '</li>',
-            'nodeDecorator' => function ($row) use ($app) {
-                $url = $app['url_generator']->generate('admin_questions_get_categories', array('id' => $row['iid']));
-
-                return \Display::url($row['title'], $url, array('id' => $row['iid']));
+            'nodeDecorator' => function ($row) {
+                $url = $this->generateControllerUrl(
+                    'getQuestionsByCategoryAction',
+                    array('id' => $row['iid'])
+                );
+
+                return \Display::url(
+                    $row['title'],
+                    $url,
+                    array('id' => $row['iid'])
+                );
             }
             //'representationField' => 'slug',
             //'html' => true
         );
-        $cats     = $repo->findOneByIid($id);
+        $cats = $repo->findOneByIid($id);
         $htmlTree = $repo->childrenHierarchy(
             $cats, /* starting from root nodes */
             true, /* false: load all children, true: only direct */
@@ -127,15 +133,16 @@ class QuestionManagerController
 
     /**
      * Gets the question list per category
-     * @param Application $app
+     * @Route("/get_questions_by_category")
+     * @Method({"GET"})
      * @param $categoryId
      * @return Response
      */
-    public function getQuestionsByCategoryAction(Application $app, $categoryId)
+    public function getQuestionsByCategoryAction($categoryId)
     {
         // Getting CQuizCategory repo.
         /** @var \Doctrine\ORM\EntityManager $em */
-        $em   = $app['orm.em'];
+        $em   = $this->getManager();
         $repo = $em->getRepository('ChamiloLMS\Entity\CQuizCategory');
 
         /** @var \ChamiloLMS\Entity\CQuizCategory $category */
@@ -149,7 +156,7 @@ class QuestionManagerController
         $grid = \Display::grid_html('questions');
 
         //jqgrid will use this URL to do the selects
-        $url = $app['url_generator']->generate('model_ajax').'?a=get_questions&categoryId='.$categoryId;
+        $url = $this->generateUrl('model_ajax').'?a=get_questions&categoryId='.$categoryId;
 
         $extraParams['postData'] = array(
             'filters' => array(
@@ -163,7 +170,7 @@ class QuestionManagerController
         // Height auto.
         $extraParams['height'] = 'auto';
         $token                 = null;
-        $editUrl               = $app['url_generator']->generate('admin_questions');
+        $editUrl = $this->generateControllerUrl('getQuestionsAction');
 
         $actionLinks = 'function action_formatter(cellvalue, options, rowObject) {
             return \'<a href="'.$editUrl.'/\'+rowObject[0]+\'/edit">'.\Display::return_icon(
@@ -188,32 +195,33 @@ class QuestionManagerController
             true
         );
         //$count = $repo->childCount($category);
-        $app['template']->assign('category_children', $count);
-        $app['template']->assign('category', $category);
-        $app['template']->assign('grid', $grid);
-        $app['template']->assign('js', $js);
+        $this->getTemplate()->assign('category_children', $count);
+        $this->getTemplate()->assign('category', $category);
+        $this->getTemplate()->assign('grid', $grid);
+        $this->getTemplate()->assign('js', $js);
 
-        $response = $app['template']->render_template('admin/questionmanager/questions.tpl');
+        $response = $this->renderTemplate('questions.tpl');
 
         return new Response($response, 200, array());
     }
 
     /**
      * Index of the question manager
-     * @param Application $app
+     * @Route("/questions")
+     * @Method({"GET"})
      * @return Response
      *
      */
-    public function questionsAction(Application $app)
+    public function getQuestionsAction($categoryId = null)
     {
-        $app['template']->addResource(api_get_jqgrid_js());
+        //$this->getTemplate()->addResource(api_get_jqgrid_js());
 
         // Getting CQuizCategory repo.
         /** @var \Gedmo\Tree\Entity\Repository\NestedTreeRepository $repo */
-        $repo = $app['orm.em']->getRepository('ChamiloLMS\Entity\CQuizCategory');
 
-        $categoryId = $app['request']->get('categoryId');
-        $subtree    = null;
+        $repo = $this->getManager()->getRepository('ChamiloLMS\Entity\CQuizCategory');
+        $categoryId = $this->getRequest()->get('categoryId');
+        $subtree = null;
 
         if (isset($categoryId)) {
             //$repo->getChildrenQueryBuilder();
@@ -241,8 +249,11 @@ class QuestionManagerController
             'rootClose'     => '</ul>',
             'childOpen'     => '<li>',
             'childClose'    => '</li>',
-            'nodeDecorator' => function ($row) use ($app, $categoryId, $subtree) {
-                $url   = $app['url_generator']->generate('admin_questions_get_categories', array('id' => $row['iid']));
+            'nodeDecorator' => function ($row) use ($categoryId, $subtree) {
+                $url   = $this->generateUrl(
+                    'question_manager.controller:getQuestionsByCategoryAction',
+                    array('id' => $row['iid'])
+                );
                 $title = $row['title'];
                 $url   = \Display::url($title, $url, array('id' => $row['iid']));
                 if ($row['iid'] == $categoryId) {
@@ -257,22 +268,22 @@ class QuestionManagerController
 
         // Getting all categories only first level lvl=1
         /** @var \Doctrine\ORM\QueryBuilder $qb */
-        $qb = $app['orm.em']->createQueryBuilder()
+
+        $qb = $this->getManager()->createQueryBuilder()
             ->select('node')
             ->from('ChamiloLMS\Entity\CQuizCategory', 'node')
             ->where('node.cId <> 0 AND node.lvl = 0')
             ->orderBy('node.root, node.lft', 'ASC');
 
-
         //$node = null, $direct = false, $sortByField = null, $direction = 'ASC', $includeNode = false
         //$qb = $repo->getChildrenQueryBuilder(null, true, 'title', 'ASC', true);
         $query = $qb->getQuery();
         $tree  = $repo->buildTree($query->getArrayResult(), $options);
 
-        $app['template']->assign('category_tree', $tree);
+        $this->getTemplate()->assign('category_tree', $tree);
 
         // Getting globals
-        $query = $app['orm.em']
+        $query = $this->getManager()
             ->createQueryBuilder()
             ->select('node')
             ->from('ChamiloLMS\Entity\CQuizCategory', 'node')
@@ -281,64 +292,72 @@ class QuestionManagerController
             ->getQuery();
 
         $tree = $repo->buildTree($query->getArrayResult(), $options);
-        $app['template']->assign('global_category_tree', $tree);
+        $this->getTemplate()->assign('global_category_tree', $tree);
 
-        $response = $app['template']->render_template('admin/questionmanager/question_categories.tpl');
+        $response = $this->renderTemplate('question_categories.tpl');
 
         return new Response($response, 200, array());
-
     }
 
     /**
      * New category
-     *
-     * @param Application $app
+     * @Route("/new_category")
+     * @Method({"GET"})
      * @return Response
      */
-    public function newCategoryAction(Application $app)
+    public function newCategoryAction()
     {
-        $url  = $app['url_generator']->generate('admin_category_new');
+        $url  = $this->generateUrl('question_manager.controller:newCategoryAction');
         $form = new \FormValidator('new', 'post', $url);
 
         $objcat = new \Testcategory();
         $objcat->getForm($form, 'new');
         $message = null;
         if ($form->validate()) {
-            $values     = $form->getSubmitValues();
-            $parent_id  = isset($values['parent_id']) && isset($values['parent_id'][0]) ? $values['parent_id'][0] : null;
-            $objcat     = new \Testcategory(0, $values['category_name'], $values['category_description'], $parent_id, 'global');
-            $categoryId = $objcat->addCategoryInBDD();
+            $values = $form->getSubmitValues();
+
+            $parent_id = isset($values['parent_id']) && isset($values['parent_id'][0]) ? $values['parent_id'][0] : null;
+            $category = new \Testcategory(
+                0,
+                $values['category_name'],
+                $values['category_description'],
+                $parent_id,
+                'global'
+            );
+            $categoryId = $category->addCategoryInBDD();
+
             if ($categoryId) {
-                $message = \Display::return_message(get_lang('AddCategoryDone'), 'confirmation');
-                //$url = $app['url_generator']->generate('admin_category_show', array('id' => $categoryId));
-                $url = $app['url_generator']->generate('admin_questions');
-                return $app->redirect($url);
+                $this->addMessage(get_lang('AddCategoryDone'), 'confirmation');
+                //$message = \Display::return_message(get_lang('AddCategoryDone'), 'confirmation');
+                //$url = $this->generateUrl('admin_category_show', array('id' => $categoryId));
+                $url = $this->generateUrl('question_manager.controller:indexAction');
+                return $this->redirect($url);
             } else {
-                $message = \Display::return_message(get_lang('AddCategoryNameAlreadyExists'), 'warning');
+                $this->addMessage(get_lang('AddCategoryNameAlreadyExists'), 'warning');
             }
         }
-        $app['template']->assign('form', $form->toHtml());
-        $response = $app['template']->render_template('admin/questionmanager/edit_category.tpl');
+        $this->getTemplate()->assign('form', $form->toHtml());
+        $response = $this->renderTemplate('edit_category.tpl');
 
         return new Response($response, 200, array());
     }
 
     /**
      * Edit category
-     *
-     * @param Application $app
+     * @Route("/edit_category")
+     * @Method({"GET"})
      * @param $id
      * @return Response
      */
-    public function editCategoryAction(Application $app, $id)
+    public function editCategoryAction($id)
     {
         $objcat = new \Testcategory($id);
 
         if (!empty($objcat->c_id) || empty($objcat->id)) {
-            $app->abort(401);
+            $this->abort(401);
         }
 
-        $url  = $app['url_generator']->generate('admin_category_edit', array('id' => $id));
+        $url  = $this->generateUrl('editCategoryAction', array('id' => $id));
         $form = new \FormValidator('edit', 'post', $url);
 
         $objcat->getForm($form, 'edit');
@@ -353,32 +372,33 @@ class QuestionManagerController
                 'global'
             );
             if ($objcat->modifyCategory()) {
-                $message = \Display::return_message(get_lang('MofidfyCategoryDone'), 'confirmation');
+                $this->addMessage(get_lang('MofidfyCategoryDone'), 'confirmation');
             } else {
-                $message = \Display::return_message(get_lang('ModifyCategoryError'), 'warning');
+                $this->addMessage(get_lang('ModifyCategoryError'), 'warning');
             }
-            $url = $app['url_generator']->generate('admin_questions');
-            return $app->redirect($url);
+            $url = $this->generateUrl('admin_questions');
+            return $this->redirect($url);
         }
-        $app['template']->assign('message', $message);
-        $app['template']->assign('form', $form->toHtml());
-        $response = $app['template']->render_template('admin/questionmanager/edit_category.tpl');
+        $this->getTemplate()->assign('message', $message);
+        $this->getTemplate()->assign('form', $form->toHtml());
+        $response = $this->renderTemplate('edit_category.tpl');
 
         return new Response($response, 200, array());
     }
 
     /**
-     * @param Application $app
+     * @Route("/delete_category")
+     * @Method({"GET"})
      * @param int $id
      *
      * @return Response
      */
-    public function deleteCategoryAction(Application $app, $id)
+    public function deleteCategoryAction($id)
     {
-        $repo     = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\CQuizCategory');
+        $repo = $this->getManager()->getRepository('ChamiloLMS\Entity\CQuizCategory');
         $category = $repo->find($id);
         if (empty($category)) {
-            $app->abort(404);
+            $this->abort(404);
         }
         $count = $repo->childCount($category);
 
@@ -388,11 +408,11 @@ class QuestionManagerController
             if ($count == 0) {
                 $objcat = new \Testcategory($id);
                 $objcat->removeCategory();
-                $url = $app['url_generator']->generate('admin_questions');
+                $url = $this->generateUrl('admin_questions');
             }
-            return $app->redirect($url);
+            return $this->redirect($url);
         } else {
-            $app->abort(401);
+            $this->abort(401);
         }
     }
 
@@ -400,25 +420,21 @@ class QuestionManagerController
     /**
      * Show category
      *
-     * @param Application $app
      * @param $id
      * @return Response
      */
-    public function showCategoryAction(Application $app, $id)
+    public function showCategoryAction($id)
     {
         $objcat = new \Testcategory($id);
 
         if (!empty($objcat->c_id)) {
-            $app->abort(401);
+            $this->abort(401);
         }
 
-        $app['template']->assign('category', $objcat);
+        $this->getTemplate()->assign('category', $objcat);
 
-        $response = $app['template']->render_template('admin/questionmanager/show_category.tpl');
+        $response = $this->renderTemplate('show_category.tpl');
 
         return new Response($response, 200, array());
     }
-
-
-
 }

+ 3 - 2
src/ChamiloLMS/Controller/CertificateController.php → src/ChamiloLMS/Controller/App/Certificate/CertificateController.php

@@ -1,8 +1,9 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-namespace ChamiloLMS\Controller;
+namespace ChamiloLMS\Controller\App\Certificate;
 
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
 
@@ -11,7 +12,7 @@ use Symfony\Component\HttpFoundation\Response;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class CertificateController
+class CertificateController extends BaseController
 {
     /**
      * @param $id

+ 3 - 2
src/ChamiloLMS/Controller/EditorController.php → src/ChamiloLMS/Controller/App/Editor/EditorController.php

@@ -1,8 +1,9 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-namespace ChamiloLMS\Controller;
+namespace ChamiloLMS\Controller\App\Editor;
 
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
 use ChamiloLMS\Component\Editor\Connector;
@@ -16,7 +17,7 @@ use ChamiloLMS\Component\Editor\Driver\elFinderVolumePersonalDriver;
  * @package ChamiloLMS.Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class EditorController extends CommonController
+class EditorController extends BaseController
 {
     /**
      * Gets that rm.wav sound

+ 1 - 1
src/ChamiloLMS/Controller/ModelAjaxController.php → src/ChamiloLMS/Controller/App/ModelAjax/ModelAjaxController.php

@@ -1,7 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-namespace ChamiloLMS\Controller;
+namespace ChamiloLMS\Controller\App\ModelAjax;
 
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;

+ 29 - 20
src/ChamiloLMS/Controller/NewsController.php → src/ChamiloLMS/Controller/App/News/NewsController.php

@@ -1,58 +1,67 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-namespace ChamiloLMS\Controller;
+namespace ChamiloLMS\Controller\App\News;
 
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
 
+use Symfony\Component\Routing\Annotation\Route;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+
 /**
  * Class NewsController
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\App\News
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class NewsController
+class NewsController extends BaseController
 {
     /**
-     *
-     * @return string
+     * @Route("/")
+     * @Method({"GET"})
+     * @return Response
      */
-    public function indexAction(Application $app, $id)
+    public function indexAction()
     {
-        $actions = null;
-        if (api_is_platform_admin()) {
-            $actions = '<a href="'.api_get_path(WEB_PATH).'main/admin/system_announcements.php">'.\Display::return_icon('edit.png', get_lang('EditSystemAnnouncement'), array(), 32).'</a>';
-        }
-
         if (api_is_anonymous()) {
             $visibility = \SystemAnnouncementManager::VISIBLE_GUEST;
         } else {
             $visibility = api_is_allowed_to_create_course() ? \SystemAnnouncementManager::VISIBLE_TEACHER : \SystemAnnouncementManager::VISIBLE_STUDENT;
         }
-        $content =  \SystemAnnouncementManager::displayAnnouncementsList($visibility, $id, 'full');
+        $content = \SystemAnnouncementManager::displayAnnouncementsList($visibility, null, 'resumed');
 
-        $app['template']->assign('content', $content);
-        $app['template']->assign('actions', $actions);
-        $response = $app['template']->renderLayout('layout_1_col.tpl');
+        $this->getTemplate()->assign('content', $content);
+        $response = $this->getTemplate()->renderLayout('layout_1_col.tpl');
 
         return new Response($response, 200, array());
     }
 
     /**
-     * @param Application $app
+     * @Route("/news/{id}")
+     * @Method({"GET"})
      * @return Response
      */
-    public function newsAction(Application $app)
+    public function getNewsAction($id = null)
     {
+        $actions = null;
+        if (api_is_platform_admin()) {
+            $actions = '<a href="'.api_get_path(WEB_PATH).'main/admin/system_announcements.php">'.\Display::return_icon('edit.png', get_lang('EditSystemAnnouncement'), array(), 32).'</a>';
+        }
+
         if (api_is_anonymous()) {
             $visibility = \SystemAnnouncementManager::VISIBLE_GUEST;
         } else {
             $visibility = api_is_allowed_to_create_course() ? \SystemAnnouncementManager::VISIBLE_TEACHER : \SystemAnnouncementManager::VISIBLE_STUDENT;
         }
-        $content =  \SystemAnnouncementManager::displayAnnouncementsList($visibility, null, 'resumed');
-        $app['template']->assign('content', $content);
-        $response = $app['template']->renderLayout('layout_1_col.tpl');
+
+        $content =  \SystemAnnouncementManager::displayAnnouncementsList($visibility, $id, 'full');
+
+        $this->getTemplate()->assign('content', $content);
+        $this->getTemplate()->assign('actions', $actions);
+        $response = $this->getTemplate()->renderLayout('layout_1_col.tpl');
 
         return new Response($response, 200, array());
     }
+
 }

+ 23 - 44
src/ChamiloLMS/Controller/App/SessionPath/SessionPathController.php

@@ -4,7 +4,7 @@
 namespace ChamiloLMS\Controller\App\SessionPath;
 
 use Silex\Application;
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Symfony\Component\HttpFoundation\Response;
 
 use Symfony\Component\Routing\Annotation\Route;
@@ -17,15 +17,32 @@ use ChamiloLMS\Form\SessionPathType;
  * @package ChamiloLMS.Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class SessionPathController extends CommonController
+class SessionPathController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\SessionPath';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'session_path.controller';
+    }
+
     /**
-     * @Route("/")
-     * @Method({"GET"})
+     * {@inheritdoc}
      */
-    public function indexAction()
+    public function getTemplatePath()
     {
-        return $this->listingAction();
+        return 'app/session_path/';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\SessionPathType';
     }
 
     /**
@@ -75,42 +92,4 @@ class SessionPathController extends CommonController
 
         $this->readEntity($id);
     }
-
-    protected function getControllerAlias()
-    {
-        return 'session_path.controller';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getTemplatePath()
-    {
-        return 'app/session_path/';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\SessionPath');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new SessionPath();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new SessionPathType();
-    }
-
 }

+ 13 - 35
src/ChamiloLMS/Controller/App/SessionPath/SessionTreeController.php

@@ -4,7 +4,7 @@
 namespace ChamiloLMS\Controller\App\SessionPath;
 
 use Silex\Application;
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\BaseController;
 use Symfony\Component\HttpFoundation\Response;
 
 use Symfony\Component\Routing\Annotation\Route;
@@ -17,61 +17,39 @@ use ChamiloLMS\Form\SessionTreeType;
  * @package ChamiloLMS.Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class SessionTreeController extends CommonController
+class SessionTreeController extends BaseController
 {
-    /**
-     * @Route("/")
-     * @Method({"GET"})
-     */
-    public function indexAction()
-    {
-        return $this->listingAction();
-    }
-
-    /**
-     * @Route("/add_item")
-     * @Method({"GET"})
-     */
-    public function addTreeItemAction()
+    public function getClass()
     {
-        return $this->addAction();
+        return 'ChamiloLMS\Entity\SessionTree';
     }
 
-    protected function getControllerAlias()
+    public function getType()
     {
-        return 'session_tree.controller';
+        return 'ChamiloLMS\Form\SessionTreeType';
     }
 
     /**
      * {@inheritdoc}
      */
-    protected function getTemplatePath()
+    public function getTemplatePath()
     {
         return 'app/session_path/session_tree/';
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
+    public function getControllerAlias()
     {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\SessionTree');
+        return 'session_tree.controller';
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new SessionTree();
-    }
 
     /**
-     * {@inheritdoc}
+     * @Route("/add_item")
+     * @Method({"GET"})
      */
-    protected function getFormType()
+    public function addTreeItemAction()
     {
-        return new SessionTreeType();
+        return $this->addAction();
     }
 
 }

+ 364 - 366
src/ChamiloLMS/Controller/BaseController.php

@@ -4,19 +4,21 @@
 namespace ChamiloLMS\Controller;
 
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
+use Knp\Menu\Matcher\Matcher;
 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
-use Doctrine\ORM\Query;
-use Doctrine\ORM\NoResultException;
 use Silex\Application;
 use Flint\Controller\Controller as FlintController;
-
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+use Symfony\Component\DependencyInjection\Container;
+
+use Knp\Menu\FactoryInterface as MenuFactoryInterface;
+use Knp\Menu\ItemInterface as MenuItemInterface;
+use Knp\Menu\Renderer\ListRenderer;
 
 /**
  * Each entity controller must extends this class.
@@ -27,54 +29,203 @@ abstract class BaseController extends FlintController
 {
     protected $app;
     protected $pimple;
+    private $classParts;
+    protected $breadcrumbs = array();
+    protected $classNameLabel;
 
     /**
-     * This method should return the entity's repository.
-     *
-     * @abstract
-     * @return \Doctrine\ORM\EntityRepository
+     * @param Application $app
      */
-    abstract protected function getRepository();
+    public function __construct(Application $app)
+    {
+        $this->app = $app;
+        // In order to use the Flint Controller.
+        $this->pimple = $app;
+
+        $className = get_class($this);
+        $this->classParts = explode('\\', Container::underscore($className));
+
+        //if (!$this->classnameLabel) {
+        $this->classNameLabel = str_replace('Controller', '', substr($className, strrpos($className, '\\') + 1));
+        //}
+    }
 
     /**
-     * This method should return a new entity instance to be used for the "create" action.
+     * @return array
+     */
+    protected function getClassParts()
+    {
+        return $this->classParts;
+    }
+
+    /**
+     * Converts string 'ChamiloLMS\Controller\Admin\QuestionManager' into
+     * 'admin/question_manager'
+     */
+    public function getTemplatePath()
+    {
+        $parts = $this->classParts;
+
+        $newPath = array();
+        foreach ($parts as $part) {
+            if (in_array($part, array('chamilo_lms', 'controller'))
+                //strpos($part, '_controller') > 0
+            ) {
+                continue;
+            }
+            $newPath[] = $part;
+        }
+
+        $template = implode('/', $newPath);
+        return str_replace('_controller', '', $template);
+    }
+
+    /**
+     * Transforms 'QuestionManagerController' to 'question_manager.controller'
+     * @return string
+     */
+    public function getControllerAlias()
+    {
+        $parts = $this->classParts;
+        $parts = array_reverse($parts);
+        $alias = str_replace('_controller', '.controller', $parts[0]);
+        return $alias;
+    }
+
+    /**
+     * Translator shortcut
+     * @param string $variable
+     * @return string
+     */
+    public function trans($variable)
+    {
+        return $this->get('translator')->trans($variable);
+    }
+
+    /**
+     * Returns the class name label
+     * @example RoleController -> Role
      *
-     * @abstract
-     * @return Object
+     * @return string the class name label
      */
-    abstract protected function getNewEntity();
+    public function getClassNameLabel()
+    {
+        return $this->classNameLabel;
+    }
 
     /**
-     * Returns a new Form Type
-     * @return AbstractType
+     * @return MenuFactoryInterface
      */
-    abstract protected function getFormType();
+    public function getMenuFactory()
+    {
+        return $this->get('knp_menu.factory');
+    }
 
     /**
-     * Returns the template path
-     * */
-    abstract protected function getTemplatePath();
+     * @param string $action
+     * @return MenuItemInterface
+     */
+    protected function getBreadcrumbs($action)
+    {
+        $breadcrumbs = $this->buildBreadcrumbs($action);
+
+        return $breadcrumbs;
+    }
+
+    /** Main home URL
+     * @return MenuItemInterface
+     */
+    protected function getHomeBreadCrumb()
+    {
+        $menu = $this->getMenuFactory()->createItem(
+            'root',
+            array(
+                'childrenAttributes' => array(
+                    'class'        => 'breadcrumb',
+                    'currentClass' => 'active'
+                )
+            )
+        );
+
+        $menu->addChild(
+            $this->trans('Home'),
+            array('uri' => $this->generateUrl('home'))
+        );
+
+        return $menu;
+    }
 
     /**
-     * Returns the controller alias
-     * @example for QuestionScoreController: question_score_controller
+     * @param $action
+     * @param MenuItemInterface $menu
+     * @return MenuItemInterface
      */
-    abstract protected function getControllerAlias();
+    public function buildBreadcrumbs($action, MenuItemInterface $menu = null)
+    {
+        if (!$menu) {
+            $menu = $this->getHomeBreadCrumb();
+        }
+
+        $menu->addChild(
+            $this->trans($this->getClassnameLabel().'List'),
+            array('uri' => $this->generateControllerUrl('listingAction'))
+        );
+
+        $action = str_replace(
+            array($this->getControllerAlias().':', 'Action'),
+            '',
+            $action
+        );
+
+        switch ($action) {
+            case 'add':
+            case 'edit':
+                $menu->addChild(
+                    $this->trans($this->getClassnameLabel().ucfirst($action))
+                    //array('uri' => $this->generateControllerUrl($action.'Action'))
+                );
+                break;
+        }
+
+        return $menu;
+    }
 
     /**
-     * Array with links
-     * @return array
+     * @param array $breadCrumbList
+     * @return string
      */
-    abstract protected function generateLinks();
+    protected function parseLegacyBreadCrumb($breadCrumbList = array())
+    {
+        $menu = $this->getHomeBreadCrumb();
+        foreach ($breadCrumbList as $item) {
+            $menu->addChild(
+                $this->trans($item['title']),
+                array('uri' => $item['url'])
+            );
+        }
+
+        $renderer = new ListRenderer(new \Knp\Menu\Matcher\Matcher());
+        $result = $renderer->render($menu);
+
+        return $result;
+    }
 
     /**
-     * @param Application $app
+     * Renders the current controller template
+     * @param string $name
+     * @param array $elements
+     * @return mixed
      */
-    public function __construct(Application $app)
+    public function renderTemplate($name, $elements = array())
     {
-        $this->app = $app;
-        // In order to use the Flint Controller.
-        $this->pimple = $app;
+        $name = $this->getTemplatePath().'/'.$name;
+
+        $renderer = new ListRenderer(new \Knp\Menu\Matcher\Matcher());
+        $action = $this->getRequest()->get('_route');
+        $result = $renderer->render($this->getBreadcrumbs($action));
+        $elements['new_breadcrumb'] = $result;
+
+        return $this->getTemplate()->renderTemplate($name, $elements);
     }
 
     /**
@@ -100,7 +251,15 @@ abstract class BaseController extends FlintController
     }
 
     /**
-     * @return \Template
+     * @return null|\Symfony\Component\HttpFoundation\Session\SessionInterface
+     */
+    protected function getSessionHandler()
+    {
+        return $this->getRequest()->getSession();
+    }
+
+    /**
+     * @return \ChamiloLMS\Framework\Template
      */
     protected function getTemplate()
     {
@@ -138,7 +297,7 @@ abstract class BaseController extends FlintController
     {
         $user = parent::getUser();
         if (empty($user)) {
-            return $this->abort(404, 'Login required.');
+            return $this->abort(404, $this->trans('Login required.'));
         }
         return $user;
     }
@@ -159,6 +318,28 @@ abstract class BaseController extends FlintController
         return $this->get('orm.em');
     }
 
+    /**
+     * @return \Doctrine\DBAL\Connection
+     */
+    protected function getDatabase()
+    {
+        return $this->get('db');
+    }
+
+    /**
+     * Shortcut of
+     * $this->getManager()->getRepository('ChamiloLMS\Entity\MyClass')
+     * @param string $entity
+     * @return \Doctrine\ORM\EntityRepository
+     */
+    /*sprotected function getRepository($entity)
+    {
+        return $this->getManager()->getRepository('ChamiloLMS\Entity\\'.$entity);
+    }*/
+
+    /**
+     * @see \Silex\Application::sendFile
+     */
     public function sendFile($file, $status = 200, $headers = array(), $contentDisposition = null)
     {
         return $this->pimple->sendFile($file, $status, $headers, $contentDisposition);
@@ -169,6 +350,7 @@ abstract class BaseController extends FlintController
      * @param string $label
      * @param array
      * @return mixed
+     * @deprecated
      */
     protected function createUrl($label, $parameters = array())
     {
@@ -216,186 +398,39 @@ abstract class BaseController extends FlintController
     /**
      * @see Symfony\Component\Routing\RouterInterface::generate()
      */
-    public function generateUrl($name, array $parameters = array(), $reference = UrlGeneratorInterface::ABSOLUTE_PATH)
-    {
-        $course = $this->getCourse();
-        if (!empty($course)) {
-            $parameters['course'] = $course->getCode();
-        }
-        $session = $this->getSession();
-        if (!empty($session)) {
-            $parameters['id_session'] = $session->getId();
-        }
-
-        return parent::generateUrl($name, $parameters, $reference);
-    }
-
-    // CRUD default actions
-
-    /**
-     * @Route("/")
-     * @Method({"GET"})
-     */
-    public function listingAction()
-    {
-        $items = $this->listAction('array');
-        $template = $this->getTemplate();
-        $template->assign('items', $items);
-        $template->assign('links', $this->generateLinks());
-        $response = $template->renderTemplate($this->getTemplatePath().'list.tpl');
-        return new Response($response, 200, array());
-    }
-
-    /**
-     *
-     * @Route("/add")
-     * @Method({"GET"})
-     */
-    public function addAction()
-    {
-        $request = $this->getRequest();
-        $form = $this->createForm($this->getFormType(), $this->getDefaultEntity());
-
-        $form->handleRequest($request);
-
-        if ($form->isValid()) {
-            $item = $form->getData();
-            $this->createAction($item);
-            $this->get('session')->getFlashBag()->add('success', "Added");
-            $url = $this->createUrl('list_link');
-            return $this->redirect($url);
-        }
-
-        $template = $this->getTemplate();
-        $template->assign('links', $this->generateLinks());
-        $template->assign('form', $form->createView());
-        $response = $template->renderTemplate($this->getTemplatePath().'add.tpl');
-        return new Response($response, 200, array());
-    }
-
-    /**
-     *
-     * @Route("/{id}", requirements={"id" = "\d+"})
-     * @Method({"GET"})
-     */
-    public function readAction($id)
-    {
-        $template = $this->getTemplate();
-        $template->assign('links', $this->generateLinks());
-        return $this->readEntity($id);
-    }
-
-    /**
-     *
-     * @Route("/{id}/edit", requirements={"id" = "\d+"})
-     * @Method({"GET"})
-     */
-    public function editAction($id)
-    {
-        $repo = $this->getRepository();
-        $request = $this->getRequest();
-        $item = $repo->findOneById($id);
-
-        if ($item) {
-
-            $form = $this->createForm($this->getFormType(), $item);
-
-            $form->handleRequest($request);
-
-            if ($form->isValid()) {
-                $data = $form->getData();
-                $this->updateAction($data);
-                $this->get('session')->getFlashBag()->add('success', "Updated");
-                $url = $this->createUrl('list_link');
-                return $this->redirect($url);
+    public function generateUrl(
+        $name,
+        array $parameters = array(),
+        $reference = UrlGeneratorInterface::ABSOLUTE_PATH
+    ) {
+        if ($name != 'home') {
+            $course = $this->getCourse();
+            if (!empty($course)) {
+                $parameters['cidReq'] = $course->getCode();
+            }
+            $session = $this->getSession();
+            if (!empty($session)) {
+                $parameters['id_session'] = $session->getId();
             }
-
-            $template = $this->getTemplate();
-            $template->assign('item', $item);
-            $template->assign('form', $form->createView());
-            $template->assign('links', $this->generateLinks());
-            $response = $template->renderTemplate($this->getTemplatePath().'edit.tpl');
-            return new Response($response, 200, array());
-        } else {
-            return $this->createNotFoundException();
-        }
-    }
-
-    /**
-     * @Route("/{id}/delete", requirements={"id" = "\d+"})
-     * @Method({"GET"})
-     */
-    public function deleteAction($id)
-    {
-        $result = $this->removeEntity($id);
-        if ($result) {
-            $url = $this->createUrl('list_link');
-            $this->get('session')->getFlashBag()->add('success', "Deleted");
-
-            return $this->redirect($url);
-        }
-    }
-
-    /**
-     * Base "read" action.
-     *
-     * @param int $id
-     * @return JsonResponse|NotFoundHttpException
-     */
-    protected function readEntity($id)
-    {
-        $entityInstance = $this->getEntityForJson($id);
-        if (false === $entityInstance) {
-            return $this->createNotFoundException();
-        }
-
-        return new JsonResponse($entityInstance);
-    }
-
-    /**
-     * Base "delete" action.
-     * @param int id
-     * @return JsonResponse|NotFoundHttpException
-     */
-    protected function removeEntity($id)
-    {
-        $object = $this->getEntity($id);
-        if (false === $object) {
-            return $this->createNotFoundException();
         }
-        $em = $this->getManager();
-        $em->remove($object);
-        $em->flush();
-        return new JsonResponse(array());
-    }
-
-    /**
-     * Base "list" action.
-     * @param string format
-     * @return JsonResponse
-     */
-    protected function listAction($format = 'json')
-    {
-        return $this->getList($format);
+        return parent::generateUrl($name, $parameters, $reference);
     }
 
     /**
-     * @param string $format
-     * @return JsonResponse
+     * In a controller like RoleController when calling the indexAction URL
+     * this function will transform to role.controller:indexAction
+     * @param string $name
+     * @param array $parameters
+     * @param bool $reference
+     * @return mixed
      */
-    protected function getList($format = 'json')
-    {
-        $qb = $this->getRepository()->createQueryBuilder('e');
-        $list = $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
-
-        switch ($format) {
-            case 'json':
-                return new JsonResponse($list);
-                break;
-            default:
-                return $list;
-                break;
-        }
+    public function generateControllerUrl(
+        $name,
+        array $parameters = array(),
+        $reference = UrlGeneratorInterface::ABSOLUTE_PATH
+    ) {
+        $name = $this->getControllerAlias().':'.$name;
+        return $this->generateUrl($name, $parameters, $reference);
     }
 
     /**
@@ -418,198 +453,161 @@ abstract class BaseController extends FlintController
     }
 
     /**
-     * Base "read" action.
-     *
-     * @param int $id
-     * @param string format
-     *
-     * @return JsonResponse|NotFoundHttpException
+     * Get system setting.
+     * @param string $variable
+     * @param string $key
+     * @return string
      */
-    protected function readActionByFormat($id, $format = 'array')
+    public function getSetting($variable, $key = null)
     {
-        $entityInstance = $this->getEntityForJson($id);
-        if (false === $entityInstance) {
-            return $this->createNotFoundException();
-        }
-        switch($format) {
-            case 'json':
-                return new JsonResponse($entityInstance);
-            case 'array':
-                return $entityInstance;
-        }
-
-        return $entityInstance;
-    }
-
-    /**
-     * Base "create" action.
-     * @param $object
-     * @return JsonResponse|NotFoundHttpException
-     */
-    protected function createAction($object)
-    {
-        if (false === $object) {
-            throw new \Exception('Unable to create the entity');
-        }
-
-        $em = $this->getManager();
-        $em->persist($object);
-        $em->flush();
-
-        return new JsonResponse($this->getEntityForJson($object->getId()));
-    }
-
-    /**
-     * Base "create" action.
-     *
-     * @return JsonResponse|NotFoundHttpException
-     */
-    protected function createJsonAction()
-    {
-        $json = $this->getJsonDataFromRequest();
-
-        if (false === $json) {
-            throw new \Exception('Invalid JSON');
-        }
-
-        $object = $this->updateEntity($this->getNewEntity(), $json);
-
-        if (false === $object) {
-            throw new \Exception('Unable to create the entity');
-        }
-        $em = $this->getManager();
-        $em->persist($object);
-        $em->flush();
-
-        return new JsonResponse($this->getEntityForJson($object->getId()));
-    }
-
-    /**
-     * Base "upload" action.
-     * @param int id
-     * @return JsonResponse|NotFoundHttpException
-     */
-    protected function updateAction($object)
-    {
-        if (false === $object) {
-            return $this->createNotFoundException();
-        }
-        $this->getManager()->flush($object);
-
-        return new JsonResponse($this->getEntityForJson($object->getId()));
-    }
-
-    /**
-     * Base "upload" action.
-     * @param int id
-     * @return JsonResponse|NotFoundHttpException
-     */
-    protected function updateJsonAction($id, $data)
-    {
-        $object = $this->getEntity($id);
-        if (false === $object) {
-            return $this->createNotFoundException();
-        }
-
-        $json = $this->getJsonDataFromRequest();
-
-        if (false === $json) {
-            throw new \Exception('Invalid JSON');
-        }
-        if (false === $this->updateEntity($object, $json)) {
-            throw new \Exception('Unable to update the entity');
+        $session = $this->getRequest()->getSession();
+        $settings = $session->get('_setting');
+        if (empty($key)) {
+            if (isset($settings[$variable])) {
+                return $settings[$variable];
+            }
+        } else {
+            if (isset($settings[$variable]) && isset($settings[$variable])) {
+                return $settings[$variable];
+            }
         }
-        $this->getManager()->flush($object);
-
-        return new JsonResponse($this->getEntityForJson($object->getId()));
     }
 
     /**
-     * Returns an entity from its ID, or FALSE in case of error.
-     *
-     * @param int $id
-     * @return Object|boolean
+     * @return bool
      */
-    protected function getEntity($id)
+    public function isCourseTeacher()
     {
-        try {
-            return $this->getRepository()->find($id);
-        } catch (NoResultException $ex) {
+        $course = $this->getCourse();
+        if (!$course) {
             return false;
-        }
-
-        return false;
-    }
+        } else {
+            if ($this->getSecurity()->isGranted('ROLE_ADMIN')) {
+                return true;
+            }
+            $course->getId();
+            $role = "ROLE_TEACHER_COURSE_".$course->getId().'_SESSION_0';
 
-    /**
-     * Returns an entity from its ID as an associative array, or FALSE in case of error.
-     *
-     * @param int $id
-     * @return array|boolean
-     */
-    protected function getEntityForJson($id)
-    {
-        try {
-            return $this->getRepository()->createQueryBuilder('e')
-                ->where('e.id = :id')
-                ->setParameter('id', $id)
-                ->getQuery()
-                ->getSingleResult(Query::HYDRATE_ARRAY);
-        } catch (NoResultException $ex) {
-            return false;
+            return $this->getSecurity()->isGranted($role);
         }
-
-        return false;
     }
 
     /**
-     * Returns the request's JSON content, or FALSE in case of error.
-     *
-     * @return string|boolean
+     * Add flash messages.
+     * @param string $message
+     * @param string $type example: info|success|warning
      */
-    protected function getJsonDataFromRequest()
+    public function addMessage($message, $type = 'info')
     {
-        $data = $this->getRequest()->getContent();
-        if (!$data) {
-            return false;
+        if ($type == 'confirmation') {
+            $type = 'info';
         }
-
-        return $data;
+        $this->get('session')->getFlashBag()->add($type, $message);
     }
 
     /**
-     * Updates an entity with data from a JSON string.
-     * Returns the entity, or FALSE in case of error.
-     *
-     * @param Object $entity
-     * @param string $data
-     * @return Object|boolean
+     * @param array $breadcrumbs
+     * @deprecated
      */
-    protected function updateEntity($entity, $data)
+    protected function setBreadcrumb($breadcrumbs)
     {
-        $data = json_decode($data, true);
+        $course = $this->getCourse();
+        //$session =  $this->getSession();
 
-        if ($data == null) {
-            return false;
+        // Adding course breadcrumb.
+        if (!empty($course)) {
+            $courseBreadcrumb = array(
+                'name' => \Display::return_icon('home.png').' '.$course->getTitle(),
+                'url' => array(
+                    'route' => 'course',
+                    'routeParameters' => array(
+                        'cidReq' => $course->getCode(),
+                        'id_session' => api_get_session_id()
+                    )
+                )
+            );
+            array_unshift($breadcrumbs, $courseBreadcrumb);
         }
 
-        foreach ($data as $name => $value) {
-            if ($name != 'id') {
-                $setter = 'set'.ucfirst($name);
-                if (method_exists($entity, $setter)) {
-                    call_user_func_array(array($entity, $setter), array($value));
+        $app = $this->app;
+
+        $app['main_breadcrumb'] = function ($app) use ($breadcrumbs) {
+            /** @var \Knp\Menu\MenuItem $menu */
+            $menu = $app['knp_menu.factory']->createItem(
+                'root',
+                array(
+                    'childrenAttributes' => array(
+                        'class'        => 'breadcrumb',
+                        'currentClass' => 'active'
+                    )
+                )
+            );
+
+            if (!empty($breadcrumbs)) {
+                foreach ($breadcrumbs as $item) {
+                    if (empty($item['url'])) {
+                        $item['url'] = array();
+                    }
+                    $menu->addChild($item['name'], $item['url']);
                 }
             }
-        }
 
-        return $entity;
+            return $menu;
+        };
+
+        $matcher = new Matcher();
+        $voter = new \Knp\Menu\Silex\Voter\RouteVoter();
+        $voter->setRequest($this->getRequest());
+        $matcher->addVoter($voter);
+        $renderer = new \Knp\Menu\Renderer\TwigRenderer(
+            $this->get('twig'),
+            'bread.tpl',
+            $matcher
+        );
+        $bread = $renderer->render(
+            $this->get('main_breadcrumb'),
+            array(
+                'template' => 'default/layout/bread.tpl'
+            )
+        );
+        $app['breadcrumbs'] = $bread;
     }
 
     /**
-     * @return null
+     * @return array
      */
-    protected function getDefaultEntity()
+    public function menuList()
+    {
+        return array(
+            'index',
+            'users' => array(
+                'list', 'add', 'edit', 'export', 'import', 'profiling', 'roles'
+            ),
+            'courses' => array(
+                array(
+                    'list',
+                    'add',
+                    'edit',
+                    'export',
+                    'import',
+                    'add_users',
+                    'import_users',
+                    'course_categories',
+                    'extra_fields',
+                    'question_extra_fields'
+                )
+            ),
+            'sessions',
+            'classes',
+            'appearance',
+            'plugins',
+            'settings',
+            'tools'
+        );
+    }
+
+    public function before(Request $request)
     {
-        return null;
+
     }
 }

+ 0 - 155
src/ChamiloLMS/Controller/CommonController.php

@@ -1,155 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-namespace ChamiloLMS\Controller;
-
-use Silex\Application;
-use Knp\Menu\Matcher\Matcher;
-use ChamiloLMS\Controller\BaseController;
-
-
-/**
- * @package ChamiloLMS.CommonController
- * @author Julio Montoya <gugli100@gmail.com>
- * @todo improve breadcrumb management
- */
-class CommonController extends BaseController
-{
-    /**
-     * @return bool
-     */
-    public function isCourseTeacher()
-    {
-        $course = $this->getCourse();
-        if (!$course) {
-            return false;
-        } else {
-            if ($this->getSecurity()->isGranted('ROLE_ADMIN')) {
-                return true;
-            }
-            $course->getId();
-            $role = "ROLE_TEACHER_COURSE_".$course->getId().'_SESSION_0';
-            //var_dump($role);
-            return $this->getSecurity()->isGranted($role);
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getControllerAlias()
-    {
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function generateLinks()
-    {
-        return $this->generateDefaultCrudRoutes();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getTemplatePath()
-    {
-    }
-
-    protected function generateDefaultCrudRoutes()
-    {
-        $className = $this->getControllerAlias();
-        return array(
-            'create_link' => $className.':addAction',
-            'read_link' => $className.':readAction',
-            'update_link' => $className.':editAction',
-            'delete_link' => $className.':deleteAction',
-            'list_link' => $className.':indexAction'
-        );
-    }
-
-    /**
-     *
-     * @param array $breadcrumbs
-     */
-    protected function setBreadcrumb($breadcrumbs)
-    {
-        $course = $this->getCourse();
-        //$session =  $this->getSession();
-
-        // Adding course breadcrumb.
-        if (!empty($course)) {
-            $courseBreadcrumb = array(
-                'name' => \Display::return_icon('home.png').' '.$course->getTitle(),
-                'url' => array(
-                    'route' => 'course',
-                    'routeParameters' => array(
-                        'cidReq' => $course->getCode(),
-                        'id_session' => api_get_session_id()
-                    )
-                )
-            );
-            array_unshift($breadcrumbs, $courseBreadcrumb);
-        }
-
-        $app = $this->app;
-
-        $app['main_breadcrumb'] = function ($app) use ($breadcrumbs) {
-            /** @var  \Knp\Menu\MenuItem $menu */
-            $menu = $app['knp_menu.factory']->createItem(
-                'root',
-                array(
-                    'childrenAttributes' => array(
-                        'class'        => 'breadcrumb',
-                        'currentClass' => 'active'
-                    )
-                )
-            );
-
-            if (!empty($breadcrumbs)) {
-                foreach ($breadcrumbs as $item) {
-                    if (empty($item['url'])) {
-                        $item['url'] = array();
-                    }
-                    $menu->addChild($item['name'], $item['url']);
-                }
-            }
-
-            return $menu;
-        };
-
-        $matcher = new Matcher();
-        $voter = new \Knp\Menu\Silex\Voter\RouteVoter();
-        $voter->setRequest($this->getRequest());
-        $matcher->addVoter($voter);
-        $renderer = new \Knp\Menu\Renderer\TwigRenderer($this->get('twig'), 'bread.tpl', $matcher);
-        $bread = $renderer->render(
-            $this->get('main_breadcrumb'),
-            array(
-                'template' => 'default/layout/bread.tpl'
-            )
-        );
-        $app['breadcrumbs'] = $bread;
-    }
-}

+ 0 - 18
src/ChamiloLMS/Controller/CourseCommonController.php

@@ -1,18 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-namespace ChamiloLMS\Controller;
-
-use Silex\Application;
-use Knp\Menu\Matcher\Matcher;
-use ChamiloLMS\Controller\BaseController;
-
-/**
- * @package ChamiloLMS.CommonController
- * @author Julio Montoya <gugli100@gmail.com>
- */
-class CourseBaseController extends CommonController
-{
-
-
-}

+ 496 - 0
src/ChamiloLMS/Controller/CrudController.php

@@ -0,0 +1,496 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace ChamiloLMS\Controller;
+
+use Doctrine\ORM\Query;
+use Doctrine\ORM\NoResultException;
+use MyProject\Proxies\__CG__\OtherProject\Proxies\__CG__\stdClass;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Pagerfanta\Pagerfanta;
+use Pagerfanta\Adapter\DoctrineORMAdapter;
+use Pagerfanta\View\TwitterBootstrap3View;
+
+use Symfony\Component\Routing\Annotation\Route;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+
+/**
+ * Class CrudController
+ * @package ChamiloLMS\Controller
+ */
+abstract class CrudController extends BaseController implements CrudControllerInterface
+{
+    public $maxPerPage = 2;
+    //public $crudController = true;
+
+    /**
+     * Returns the entity's repository.
+     *
+     * @abstract
+     * @return \Doctrine\ORM\EntityRepository
+     */
+    public function getRepository()
+    {
+        return $this->get('orm.em')->getRepository($this->getClass());
+    }
+
+    /**
+     * Returns a new entity instance to be used for the "create/edit" actions.
+     *
+     * @return stdClass
+     */
+    public function getNewEntity()
+    {
+        $class = $this->getClass();
+
+        return new $class;
+    }
+
+    /**
+     * Returns a new Form Type
+     * @return \Symfony\Component\Form\AbstractType
+     */
+    public function getFormType()
+    {
+        $class = $this->getType();
+
+        return new $class;
+    }
+
+    /**
+     *
+     * @Route("/")
+     * @Method({"GET"})
+     */
+    public function indexAction()
+    {
+        $breadcrumbs = array(
+            array(
+                'name' => get_lang('Curriculum'),
+                'url' => array(
+                    'route' => 'curriculum_user.controller:indexAction',
+                    'routeParameters' => array(
+                        //'course' => $this->getCourse()->getCode()
+                    )
+                )
+            ),
+            array(
+                'name' => get_lang('Categories')
+            )
+        );
+        //$this->setBreadcrumb(array());
+
+        return $this->listingAction();
+    }
+
+    /**
+     * @Route("/")
+     * @Method({"GET"})
+     */
+    public function listingAction()
+    {
+        $template = $this->getTemplate();
+
+        // Getting query
+        $qb = $this->getRepository()->createQueryBuilder('e');
+        $query = $qb->getQuery();
+
+        // Process query in a pagination mode.
+        $adapter = new DoctrineORMAdapter($query);
+        $pager = new Pagerfanta($adapter);
+
+        $page = $this->getRequest()->get('page');
+
+        if (empty($page)) {
+            $page = 1;
+        }
+
+        $routeGenerator = function ($page) {
+            return $this->generateControllerUrl('listingAction', array('page' => $page));
+        };
+
+        $pager->setMaxPerPage($this->maxPerPage);
+        $pager->setCurrentPage($page);
+
+        $view = new TwitterBootstrap3View();
+        $pagination = $view->render($pager, $routeGenerator, array(
+            'proximity' => 3,
+        ));
+
+        $template->assign('items', $pager);
+        $template->assign('grid_pagination', $pagination);
+        $template->assign('links', $this->generateLinks());
+        $response = $this->renderTemplate('list.tpl');
+
+        return new Response($response, 200, array());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function generateLinks()
+    {
+        return $this->generateDefaultCrudRoutes();
+    }
+
+    protected function generateDefaultCrudRoutes()
+    {
+        $className = $this->getControllerAlias();
+
+        return
+            array(
+            'create_link' => $className.':addAction',
+            'read_link' => $className.':readAction',
+            'update_link' => $className.':editAction',
+            'delete_link' => $className.':deleteAction',
+            'list_link' => $className.':indexAction'
+        );
+    }
+
+    public function getLink($action)
+    {
+
+    }
+
+    /**
+     * @Route("/add")
+     * @Method({"GET"})
+     */
+    public function addAction()
+    {
+        $request = $this->getRequest();
+        $form = $this->createForm($this->getFormType(), $this->getNewEntity());
+
+        $form->handleRequest($request);
+
+        if ($form->isValid()) {
+            $item = $form->getData();
+            $this->createAction($item);
+            $this->addMessage('Added', 'success');
+            $url = $this->generateControllerUrl('listingAction');
+
+            return $this->redirect($url);
+        }
+
+        $template = $this->getTemplate();
+        $template->assign('links', $this->generateLinks());
+        $template->assign('form', $form->createView());
+        $response = $this->renderTemplate('add.tpl');
+
+        return new Response($response, 200, array());
+    }
+
+    /**
+     *
+     * @Route("/{id}", requirements={"id" = "\d+"})
+     * @Method({"GET"})
+     */
+    public function readAction($id)
+    {
+        $template = $this->getTemplate();
+        $template->assign('links', $this->generateLinks());
+        return $this->readEntity($id);
+    }
+
+    /**
+     * @Route("/{id}/edit", requirements={"id" = "\d+"})
+     * @Method({"GET"})
+     */
+    public function editAction($id)
+    {
+        $repo = $this->getRepository();
+        $request = $this->getRequest();
+        $item = $repo->findOneById($id);
+
+        if ($item) {
+            $form = $this->createForm($this->getFormType(), $item);
+
+            $form->handleRequest($request);
+
+            if ($form->isValid()) {
+                $data = $form->getData();
+                $this->updateAction($data);
+                $this->addMessage('Updated', 'success');
+                $url = $this->generateControllerUrl('listingAction');
+
+                return $this->redirect($url);
+            }
+
+            $template = $this->getTemplate();
+            $template->assign('item', $item);
+            $template->assign('form', $form->createView());
+            $template->assign('links', $this->generateLinks());
+            $response = $this->renderTemplate('edit.tpl');
+
+            return new Response($response, 200, array());
+        } else {
+            return $this->createNotFoundException();
+        }
+    }
+
+    /**
+     * @Route("/{id}/delete", requirements={"id" = "\d+"})
+     * @Method({"GET"})
+     */
+    public function deleteAction($id)
+    {
+        $result = $this->removeEntity($id);
+        if ($result) {
+            $url = $this->generateControllerUrl('listingAction');
+            $this->addMessage('Deleted', 'success');
+
+            return $this->redirect($url);
+        }
+    }
+
+    /**
+     * Base "read" action.
+     *
+     * @param int $id
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function readEntity($id)
+    {
+        $entityInstance = $this->getEntityForJson($id);
+        if (false === $entityInstance) {
+            return $this->createNotFoundException();
+        }
+
+        return new JsonResponse($entityInstance);
+    }
+
+    /**
+     * Base "delete" action.
+     * @param int id
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function removeEntity($id)
+    {
+        $object = $this->getEntity($id);
+        if (false === $object) {
+            return $this->createNotFoundException();
+        }
+        $em = $this->getManager();
+        $em->remove($object);
+        $em->flush();
+
+        return new JsonResponse(array());
+    }
+
+    /**
+     * Base "list" action.
+     * @param string format
+     * @return JsonResponse
+     */
+    protected function listAction($format = 'json')
+    {
+        return $this->getList($format);
+    }
+
+    /**
+     * @param string $format
+     * @return JsonResponse
+     */
+    protected function getList($format = 'json')
+    {
+        $qb = $this->getRepository()->createQueryBuilder('e');
+        $list = $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
+
+        switch ($format) {
+            case 'json':
+                return new JsonResponse($list);
+                break;
+            default:
+                return $list;
+                break;
+        }
+    }
+
+    /**
+     * Base "read" action.
+     *
+     * @param int $id
+     * @param string format
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function readActionByFormat($id, $format = 'array')
+    {
+        $entityInstance = $this->getEntityForJson($id);
+        if (false === $entityInstance) {
+            return $this->createNotFoundException();
+        }
+        switch($format) {
+            case 'json':
+                return new JsonResponse($entityInstance);
+            case 'array':
+                return $entityInstance;
+        }
+
+        return $entityInstance;
+    }
+
+    /**
+    * Base "create" action.
+    * @param stdClass $object
+    *
+    * @throws \Exception
+    */
+    protected function createAction($object)
+    {
+        if (false === $object) {
+            throw new \Exception('Unable to create the entity');
+        }
+
+        $em = $this->getManager();
+        $em->persist($object);
+        $em->flush();
+    }
+
+    /**
+     * Base "upload" action.
+     * @param int id
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function updateAction($object)
+    {
+        if (false === $object) {
+            return $this->createNotFoundException();
+        }
+        $this->getManager()->flush($object);
+    }
+
+    /**
+     * Returns an entity from its ID, or FALSE in case of error.
+     *
+     * @param int $id
+     * @return Object|boolean
+     */
+    protected function getEntity($id)
+    {
+        try {
+            return $this->getRepository()->find($id);
+        } catch (NoResultException $ex) {
+            return false;
+        }
+
+        return false;
+    }
+
+    // json actions
+
+    /**
+     * Base "create" action.
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function createJsonAction()
+    {
+        $json = $this->getJsonDataFromRequest();
+
+        if (false === $json) {
+            throw new \Exception('Invalid JSON');
+        }
+
+        $object = $this->updateEntity($this->getNewEntity(), $json);
+
+        if (false === $object) {
+            throw new \Exception('Unable to create the entity');
+        }
+        $em = $this->getManager();
+        $em->persist($object);
+        $em->flush();
+
+        return new JsonResponse($this->getEntityForJson($object->getId()));
+    }
+
+    /**
+     * Returns an entity from its ID as an associative array, false in error.
+     *
+     * @param int $id
+     * @return array|boolean
+     */
+    protected function getEntityForJson($id)
+    {
+        try {
+            return $this->getRepository()->createQueryBuilder('e')
+                ->where('e.id = :id')
+                ->setParameter('id', $id)
+                ->getQuery()
+                ->getSingleResult(Query::HYDRATE_ARRAY);
+        } catch (NoResultException $ex) {
+            return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the request's JSON content, or FALSE in case of error.
+     *
+     * @return string|boolean
+     */
+    protected function getJsonDataFromRequest()
+    {
+        $data = $this->getRequest()->getContent();
+        if (!$data) {
+            return false;
+        }
+
+        return $data;
+    }
+
+    /**
+     * Base "upload" action.
+     * @param int id
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function updateJsonAction($id, $data)
+    {
+        $object = $this->getEntity($id);
+        if (false === $object) {
+            return $this->createNotFoundException();
+        }
+
+        $json = $this->getJsonDataFromRequest();
+
+        if (false === $json) {
+            throw new \Exception('Invalid JSON');
+        }
+        if (false === $this->updateEntity($object, $json)) {
+            throw new \Exception('Unable to update the entity');
+        }
+        $this->getManager()->flush($object);
+
+        return new JsonResponse($this->getEntityForJson($object->getId()));
+    }
+
+    /**
+     * Updates an entity with data from a JSON string.
+     * Returns the entity, or FALSE in case of error.
+     *
+     * @param Object $entity
+     * @param string $data
+     * @return Object|boolean
+     */
+    protected function updateEntity($entity, $data)
+    {
+        $data = json_decode($data, true);
+
+        if ($data == null) {
+            return false;
+        }
+
+        foreach ($data as $name => $value) {
+            if ($name != 'id') {
+                $setter = 'set'.ucfirst($name);
+                if (method_exists($entity, $setter)) {
+                    call_user_func_array(array($entity, $setter), array($value));
+                }
+            }
+        }
+
+        return $entity;
+    }
+}

+ 37 - 0
src/ChamiloLMS/Controller/CrudControllerInterface.php

@@ -0,0 +1,37 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace ChamiloLMS\Controller;
+
+/**
+ * Interface CrudControllerInterface
+ * @package ChamiloLMS\Controller
+ */
+interface CrudControllerInterface
+{
+    /**
+     * Returns the entity class example: 'ChamiloLMS\Entity\Role'
+     * @return string
+     */
+    public function getClass();
+
+    /**
+     * Returns the form type name example: 'ChamiloLMS\Form\RoleType'
+     * @return string
+     */
+    public function getType();
+
+    /**
+     * Returns the controller alias loaded in the routes ex : 'role.controller'
+     * @return string
+     */
+    public function getControllerAlias();
+
+    /**
+     * Returns the path of the templates located in
+     * src/ChamiloLMS/Resources/views/default
+     * example : admin/administrator/role/
+     * @return string
+     */
+    public function getTemplatePath();
+}

+ 125 - 83
src/ChamiloLMS/Controller/IndexController.php

@@ -8,65 +8,24 @@ use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\Finder\Finder;
+use Symfony\Component\Routing\Annotation\Route;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * @package ChamiloLMS.Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class IndexController extends CommonController
+class IndexController extends BaseController
 {
     /**
-     * @param \Silex\Application $app
-     *
-     * @return \Symfony\Component\HttpFoundation\Response
+     * @Route("/index")
+     * @Method({"GET"})
+     * @return Response
      */
-    public function indexAction(Application $app)
+    public function indexAction()
     {
         $template = $this->getTemplate();
 
-        /*$user = $this->getManager()->getRepository('ChamiloLMS\Entity\User')->find(1);
-        foreach($user->getPortals() as $portal) {
-            var_dump($portal->getUrl());
-        }*/
-
-        /*
-        $token = $app['security']->getToken();
-        if (null !== $token) {
-            $user = $token->getUser();
-        }*/
-
-        /*\ChamiloSession::write('name', 'clara');
-        var_dump(\ChamiloSession::read('name'));
-        var_dump($_SESSION['name']);*/
-
-        //var_dump(\ChamiloSession::read('aaa'));
-
-        /*\ChamiloSession::write('name', 'clar');
-        echo \ChamiloSession::read('name');
-        $app['session']->set('name', 'julio');
-        echo $app['session']->get('name');*/
-        /*
-        $token = $app['security']->getToken();
-        if (null !== $token) {
-            $user = $token->getUser();
-            var_dump($user );
-        }
-        if ($app['security']->isGranted('ROLE_ADMIN')) {
-        }*/
-
-        /** @var \ChamiloLMS\Entity\User $user */
-        /*$em = $app['orm.ems']['db_write'];
-        $user = $em->getRepository('ChamiloLMS\Entity\User')->find(6);
-        $role = $em->getRepository('ChamiloLMS\Entity\Role')->findOneByRole('ROLE_STUDENT');
-        $user->getRolesObj()->add($role);
-        $em->persist($user);
-        $em->flush();*/
-
-        //$user->roles->add($status);
-        /*$roles = $user->getRolesObj();
-        foreach ($roles as $role) {
-        }*/
-
         // $countries = Intl::getRegionBundle()->getCountryNames('es');
         //var_dump($countries);
 
@@ -74,31 +33,19 @@ class IndexController extends CommonController
         //http://userguide.icu-project.org/formatparse/datetime for date formats
         $formatter->setPattern("EEEE d MMMM Y");
         echo $formatter->format(time());*/
+
         $extra = array();
-        if (api_get_setting('use_virtual_keyboard') == 'true') {
+        if ($this->getSetting('use_virtual_keyboard') == 'true') {
             $extra[] = api_get_css(api_get_path(WEB_LIBRARY_JS_PATH).'keyboard/keyboard.css');
             $extra[] = api_get_js('keyboard/jquery.keyboard.js');
         }
-        $app['template']->addResource(api_get_jqgrid_js(), 'string');
 
-        $app['this_section'] = SECTION_CAMPUS;
-        $request = $app['request'];
+        $template->addResource(api_get_jqgrid_js(), 'string');
 
-        if (api_get_setting('allow_terms_conditions') == 'true') {
-            unset($_SESSION['term_and_condition']);
-        }
+        $this->app['this_section'] = SECTION_CAMPUS;
 
-        // If we are not logged in and custompages activated
-        if (!api_get_user_id() && \CustomPages::enabled()) {
-            $loggedOut = $request->get('loggedout');
-            if ($loggedOut) {
-                \CustomPages::display(\CustomPages::LOGGED_OUT);
-            } else {
-                \CustomPages::display(\CustomPages::INDEX_UNLOGGED);
-            }
-        }
         /** @var \PageController $pageController */
-        $pageController = $app['page_controller'];
+        $pageController = $this->get('page_controller');
 
         if (api_get_setting('display_categories_on_homepage') == 'true') {
             $template->assign('course_category_block', $pageController->return_courses_in_categories());
@@ -110,12 +57,9 @@ class IndexController extends CommonController
             facebook_connect();
         }
 
-        $this->setLoginForm($app);
+        $this->setLoginForm();
 
         if (!api_is_anonymous()) {
-            //$pageController->setProfileBlock();
-            //$pageController->setUserImageBlock();
-
             if (api_is_platform_admin()) {
                 $pageController->setCourseBlock();
             } else {
@@ -172,10 +116,7 @@ class IndexController extends CommonController
         return new Response($response, 200, array('Cache-Control' => 's-maxage=3600, public'));
     }
 
-    /**
-     * @param \Silex\Application $app
-     */
-    public function setLoginForm(Application $app)
+    public function setLoginForm()
     {
         $userId    = api_get_user_id();
         $loginForm = null;
@@ -183,8 +124,8 @@ class IndexController extends CommonController
 
             // Only display if the user isn't logged in
 
-            $app['template']->assign('login_language_form', api_display_language_form(true));
-            $app['template']->assign('login_form', self::displayLoginForm($app));
+            $this->getTemplate()->assign('login_language_form', api_display_language_form(true));
+            $this->getTemplate()->assign('login_form', self::displayLoginForm());
 
             if (api_get_setting('allow_lostpassword') == 'true' || api_get_setting('allow_registration') == 'true') {
                 $loginForm .= '<ul class="nav nav-list">';
@@ -196,7 +137,7 @@ class IndexController extends CommonController
                 }
                 $loginForm .= '</ul>';
             }
-            $app['template']->assign('login_options', $loginForm);
+            $this->getTemplate()->assign('login_options', $loginForm);
         }
     }
 
@@ -205,7 +146,7 @@ class IndexController extends CommonController
      *
      * @return string
      */
-    public function displayLoginForm(Application $app)
+    public function displayLoginForm()
     {
         /* {{ form_widget(form) }}
           $form = $app['form.factory']->createBuilder('form')
@@ -221,7 +162,7 @@ class IndexController extends CommonController
         $form = new \FormValidator(
             'formLogin',
             'POST',
-            $app['url_generator']->generate('secured_login_check'),
+            $this->get('url_generator')->generate('secured_login_check'),
             null,
             array('class'=> 'form-signin-block')
         );
@@ -248,6 +189,7 @@ class IndexController extends CommonController
                 'icon' => 'fa fa-key fa-fw'
             )
         );
+
         $form->addElement('style_submit_button', 'submitAuth', get_lang('LoginEnter'), array('class' => 'btn btn-primary btn-block'));
         $html = $form->return_form();
 
@@ -448,18 +390,118 @@ class IndexController extends CommonController
         return \Display::return_message($message, 'error');
     }
 
+    public function dashboardAction()
+    {
+        /*$template = $this->getTemplate();
+
+        $template->assign('content', 'welcome!');
+        $response = $template->renderLayout('layout_2_col.tpl');
+
+        //return new Response($response, 200, array('Cache-Control' => 's-maxage=3600, public'));
+        return new Response($response, 200, array());*/
+    }
+
     /**
-     * @param Application $app
+     * @Route("/userportal")
+     * @Method({"GET"})
+     *
+     * @param string $type courses|sessions|mycoursecategories
+     * @param string $filter for the userportal courses page. Only works when setting 'history'
+     * @param int $page
      * @return Response
      */
-    function dashboardAction(Application $app)
+    public function userPortalAction($type = 'courses', $filter = 'current', $page = 1)
     {
+        // @todo Use filters like "after/before|finish" to manage user access
+        api_block_anonymous_users();
+
+
+        // Abort request because the user is not allowed here - @todo use filters
+        if ($this->app['allowed'] == false) {
+            return $this->abort(403, 'Not allowed');
+        }
+
+        // Main courses and session list
+        $items = null;
+        $type = str_replace('/', '', $type);
+
+        /** @var \PageController $pageController */
+        $pageController = $this->get('page_controller');
+
+        switch ($type) {
+            case 'sessions':
+                $items = $pageController->returnSessions(api_get_user_id(), $filter, $page);
+                break;
+            case 'sessioncategories':
+                $items = $pageController->returnSessionsCategories(api_get_user_id(), $filter, $page);
+                break;
+            case 'courses':
+                $items = $pageController->returnCourses(api_get_user_id(), $filter, $page);
+                break;
+            case 'mycoursecategories':
+                $items = $pageController->returnMyCourseCategories(api_get_user_id(), $filter, $page);
+                break;
+            case 'specialcourses':
+                $items = $pageController->returnSpecialCourses(api_get_user_id(), $filter, $page);
+                break;
+        }
+
         $template = $this->getTemplate();
+        //Show the chamilo mascot
+        if (empty($items) && empty($filter)) {
+            $pageController->return_welcome_to_course_block($template);
+        }
 
-        $template->assign('content', 'welcome!');
-        $response = $template->renderLayout('layout_2_col.tpl');
+        /*
+        $app['my_main_menu'] = function($app) {
+            $menu = $app['knp_menu.factory']->createItem('root');
+            $menu->addChild('Home', array('route' => api_get_path(WEB_CODE_PATH)));
+            return $menu;
+        };
+        $app['knp_menu.menus'] = array('main' => 'my_main_menu');*/
+        $template->assign('content', $items);
+        $pageController->setCourseSessionMenu();
+
+        $pageController->setProfileBlock();
+        $pageController->setUserImageBlock();
+        $pageController->setCourseBlock($filter);
+        $pageController->setSessionBlock();
+        $pageController->return_reservation_block();
+        $pageController->returnNavigationLinks($template->getNavigationLinks());
+
+        $template->assign('search_block', $pageController->return_search_block());
+        $template->assign('classes_block', $pageController->return_classes_block());
+        $pageController->returnSkillsLinks();
+
+        // Deleting the session_id.
+        $this->getSessionHandler()->remove('session_id');
+
+        $response = $template->renderTemplate('userportal/index.tpl');
 
-        //return new Response($response, 200, array('Cache-Control' => 's-maxage=3600, public'));
         return new Response($response, 200, array());
     }
+
+    /**
+     * Toggle the student view action
+     *
+     * @Route("/toggle_student_view")
+     * @Method({"GET"})
+     *
+     * @return Response
+     */
+    public function toggleStudentViewAction()
+    {
+        if (!api_is_allowed_to_edit(false, false, false, false)) {
+            return '';
+        }
+        $request = $this->getRequest();
+        $studentView = $request->getSession()->get('studentview');
+        if (empty($studentView) || $studentView == 'studentview') {
+            $request->getSession()->set('studentview', 'teacherview');
+            return 'teacherview';
+        } else {
+            $request->getSession()->set('studentview', 'studentview');
+            return 'studentview';
+        }
+    }
 }

+ 15 - 13
src/ChamiloLMS/Controller/LegacyController.php

@@ -6,7 +6,6 @@ namespace ChamiloLMS\Controller;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\Request;
-use \ChamiloSession as Session;
 
 /**
  * Class LegacyController
@@ -14,7 +13,7 @@ use \ChamiloSession as Session;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class LegacyController extends CommonController
+class LegacyController extends BaseController
 {
     public $section;
 
@@ -29,8 +28,7 @@ class LegacyController extends CommonController
     public function classicAction(Application $app, $file)
     {
         $responseHeaders = array();
-        /** @var Request $request */
-        $request = $app['request'];
+        $request = $this->getRequest();
 
         // get.
         $_GET = $request->query->all();
@@ -43,6 +41,8 @@ class LegacyController extends CommonController
 
         $fileToLoad = $mainPath.$file;
 
+        $template = $this->getTemplate();
+
         if (is_file($fileToLoad) &&
             \Security::check_abs_path($fileToLoad, $mainPath)
         ) {
@@ -70,30 +70,32 @@ class LegacyController extends CommonController
             }
 
             // Setting page header/footer conditions (important for LPs)
-            $app['template']->setFooter($app['template.show_footer']);
-            $app['template']->setHeader($app['template.show_header']);
+            $template->setFooter($app['template.show_footer']);
+            $template->setHeader($app['template.show_header']);
 
             if (isset($htmlHeadXtra)) {
-                $app['template']->addResource($htmlHeadXtra, 'string');
+                $template->addResource($htmlHeadXtra, 'string');
             }
-
+            // $interbreadcrumb is loaded in the require_once file.
             if (isset($interbreadcrumb)) {
-                $app['template']->setBreadcrumb($interbreadcrumb);
-                $app['template']->loadBreadcrumbToTemplate();
+                $template->setBreadcrumb($interbreadcrumb);
+                $breadCrumb = $template->getBreadCrumbLegacyArray();
+                $menu = $this->parseLegacyBreadCrumb($breadCrumb);
+                $template->assign('new_breadcrumb', $menu);
             }
 
-            $app['template']->parseResources();
+            $template->parseResources();
 
             if (isset($tpl)) {
                 $response = $app['twig']->render($app['default_layout']);
             } else {
-                $app['template']->assign('content', $out);
+                $template->assign('content', $out);
                 $response = $app['twig']->render($app['default_layout']);
             }
         } else {
             return $app->abort(404, 'File not found');
         }
+
         return new Response($response, 200, $responseHeaders);
     }
-
 }

+ 0 - 1
src/ChamiloLMS/Controller/Tool/CourseController.php

@@ -1 +0,0 @@
-<?php

+ 42 - 63
src/ChamiloLMS/Controller/Tool/CourseHome/CourseHomeController.php

@@ -3,9 +3,10 @@
 
 namespace ChamiloLMS\Controller\Tool\CourseHome;
 
+use ChamiloLMS\Controller\ToolBaseController;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 use ChamiloLMS\Entity\CTool;
@@ -15,26 +16,38 @@ use Display;
 
 /**
  * Class CourseHomeController
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Tool\CourseHome
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class CourseHomeController extends CommonController
+class CourseHomeController extends ToolBaseController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\CTool';
+    }
+
     /**
-     * @Route("/courses/{cidReq}/{sessionId}")
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\CourseHomeToolType';
+    }
+
+    /**
+     * @Route("/")
+     * @Route("/home")
      * @Method({"GET"})
      *
-     * @param string $cidReq
-     * @param int $id_session
      * @return Response
      */
-    public function indexAction($cidReq, $id_session = null)
+    public function indexAction()
     {
         $courseCode = api_get_course_id();
         $sessionId = api_get_session_id();
         $userId = $this->getUser()->getUserId();
 
-        $coursesAlreadyVisited = $this->getRequest()->getSession()->get('coursesAlreadyVisited');
+        $coursesAlreadyVisited = $this->getSessionHandler()->get('coursesAlreadyVisited');
 
         $result = $this->autolaunch();
 
@@ -42,21 +55,17 @@ class CourseHomeController extends CommonController
         $showAutoLaunchExerciseWarning = $result['show_autolaunch_exercise_warning'];
 
         if ($showAutoLaunchLpWarning) {
-            $this->getTemplate()->assign(
-                'lp_warning',
-                Display::return_message(get_lang('TheLPAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificLP'), 'warning')
-            );
+            $this->addMessage('TheLPAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificLP', 'warning');
         }
         if ($showAutoLaunchExerciseWarning) {
-            $this->getTemplate()->assign(
-                'exercise_warning',
-                Display::return_message(get_lang('TheExerciseAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificExercise'), 'warning')
-            );
+            $this->addMessage('TheExerciseAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificExercise', 'warning');
         }
+
         if ($this->isCourseTeacher()) {
+
             $editIcons = Display::url(
                 Display::return_icon('edit.png'),
-                $this->generateUrl('course_home.controller:iconListAction', array('course' => api_get_course_id()))
+                $this->generateControllerUrl('iconListAction', array('courseCode' => api_get_course_id()))
             );
 
             $this->getTemplate()->assign('edit_icons', $editIcons);
@@ -65,11 +74,11 @@ class CourseHomeController extends CommonController
         if (!isset($coursesAlreadyVisited[$courseCode])) {
             event_access_course();
             $coursesAlreadyVisited[$courseCode] = 1;
-            $this->getRequest()->getSession()->set('coursesAlreadyVisited', $coursesAlreadyVisited);
+            $this->getSessionHandler()->set('coursesAlreadyVisited', $coursesAlreadyVisited);
         }
 
-        $this->getRequest()->getSession()->remove('toolgroup');
-        $this->getRequest()->getSession()->remove('_gid');
+        $this->getSessionHandler()->remove('toolgroup');
+        $this->getSessionHandler()->remove('_gid');
 
         $isSpecialCourse = \CourseManager::is_special_course($courseCode);
 
@@ -108,7 +117,7 @@ class CourseHomeController extends CommonController
             $this->getTemplate()->assign('session_info', $sessionInfo);
         }
 
-        $response = $this->get('template')->render_template($this->getTemplatePath().'index.tpl');
+        $response = $this->renderTemplate('index.tpl');
 
         return new Response($response, 200, array());
     }
@@ -145,7 +154,9 @@ class CourseHomeController extends CommonController
                 $condition = '';
                 if (!empty($session_id)) {
                     $condition =  api_get_session_condition($session_id);
-                    $sql = "SELECT iid FROM $table WHERE c_id = $course_id AND autolaunch = 1 $condition LIMIT 1";
+                    $sql = "SELECT iid FROM $table
+                            WHERE c_id = $course_id AND autolaunch = 1 $condition
+                            LIMIT 1";
                     $result = \Database::query($sql);
                     //If we found nothing in the session we just called the session_id =  0 autolaunch
                     if (\Database::num_rows($result) ==  0) {
@@ -155,10 +166,12 @@ class CourseHomeController extends CommonController
                     }
                 }
 
-                $sql = "SELECT iid FROM $table WHERE c_id = $course_id AND autolaunch = 1 $condition LIMIT 1";
+                $sql = "SELECT iid FROM $table
+                        WHERE c_id = $course_id AND autolaunch = 1 $condition
+                        LIMIT 1";
                 $result = \Database::query($sql);
                 if (\Database::num_rows($result) >  0) {
-                    $data = \Database::fetch_array($result,'ASSOC');
+                    $data = \Database::fetch_array($result, 'ASSOC');
                     if (!empty($data['iid'])) {
                         if (api_is_platform_admin() || api_is_allowed_to_edit()) {
                             $showAutoLaunchExerciseWarning = true;
@@ -213,10 +226,12 @@ class CourseHomeController extends CommonController
                     }
                 }
 
-                $sql = "SELECT id FROM $lp_table WHERE c_id = $course_id AND autolunch = 1 $condition LIMIT 1";
+                $sql = "SELECT id FROM $lp_table
+                        WHERE c_id = $course_id AND autolunch = 1 $condition
+                        LIMIT 1";
                 $result = \Database::query($sql);
                 if (\Database::num_rows($result) >  0) {
-                    $lp_data = \Database::fetch_array($result,'ASSOC');
+                    $lp_data = \Database::fetch_array($result, 'ASSOC');
                     if (!empty($lp_data['id'])) {
                         if (api_is_platform_admin() || api_is_allowed_to_edit()) {
                             $showAutoLaunchLpWarning = true;
@@ -386,6 +401,7 @@ class CourseHomeController extends CommonController
         $this->getTemplate()->assign('items_from_course', $itemsFromCourse);
         $this->getTemplate()->assign('items_from_session', $itemsFromSession);
         $this->getTemplate()->assign('links', $this->generateLinks());
+
         return $this->get('template')->render_template($this->getTemplatePath().'tool/list.tpl');
     }
 
@@ -521,41 +537,4 @@ class CourseHomeController extends CommonController
         $url = $this->generateUrl('course_home.controller:iconListAction');
         return $this->redirect($url);
     }
-
-    protected function getControllerAlias()
-    {
-        return 'course_home.controller';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getTemplatePath()
-    {
-        return 'tool/course_home/';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CTool');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new CTool();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new CourseHomeToolType();
-    }
 }

+ 39 - 50
src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumCategoryController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\Tool\Curriculum;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Silex\Application;
 use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
@@ -17,8 +17,45 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class CurriculumCategoryController extends CommonController
+class CurriculumCategoryController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\CurriculumCategory';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'tool/curriculum/category/';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\CurriculumCategoryType';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'curriculum_category.controller';
+    }
+
+    protected function getDefaultEntity()
+    {
+        $entity = $this->getNewEntity();
+        $entity->setCourse($this->getCourse());
+        $session = $this->getSession();
+        if (!empty($session)) {
+            $entity->setSession($session);
+        }
+        return $entity;
+    }
+
     /**
      *
      * @Route("/")
@@ -360,10 +397,6 @@ class CurriculumCategoryController extends CommonController
         return new Response($response, 200, array());
     }
 
-    protected function getControllerAlias()
-    {
-        return 'curriculum_category.controller';
-    }
 
     protected function generateDefaultCrudRoutes()
     {
@@ -374,48 +407,4 @@ class CurriculumCategoryController extends CommonController
 
         return $routes ;
     }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'tool/curriculum/category/';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CurriculumCategory');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new CurriculumCategory();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new CurriculumCategoryType();
-    }
-
-    protected function getDefaultEntity()
-    {
-
-        $entity = $this->getNewEntity();
-        $entity->setCourse($this->getCourse());
-        $session = $this->getSession();
-        if (!empty($session)) {
-            $entity->setSession($session);
-        }
-        return $entity;
-    }
 }

+ 2 - 2
src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\Tool\Curriculum;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
@@ -17,7 +17,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class CurriculumController extends CommonController
+class CurriculumController extends BaseController
 {
     /**
      *

+ 33 - 67
src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumItemController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\Tool\Curriculum;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Silex\Application;
 use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
@@ -18,8 +18,37 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class CurriculumItemController extends CommonController
+class CurriculumItemController extends CrudController
 {
+    public function getControllerAlias()
+    {
+        return 'curriculum_item.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'tool/curriculum/item/';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\CurriculumItem';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\CurriculumItemType';
+    }
+
     /**
      *
      * @Route("/")
@@ -55,26 +84,7 @@ class CurriculumItemController extends CommonController
         return parent::listingAction();
     }
 
-    /**
-    *
-    * @Route("/{id}", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function readAction($id)
-    {
-        return parent::readAction($id);
-    }
-
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
-
-    /**
+      /**
     * @Route("/add-from-category/{id}")
     * @Method({"GET, POST"})
     */
@@ -174,20 +184,8 @@ class CurriculumItemController extends CommonController
         return parent::editAction($id);
     }
 
-    /**
-    *
-    * @Route("/{id}/delete", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function deleteAction($id)
-    {
-        return parent::deleteAction($id);
-    }
 
-    protected function getControllerAlias()
-    {
-        return 'curriculum_item.controller';
-    }
+
 
     protected function generateDefaultCrudRoutes()
     {
@@ -195,36 +193,4 @@ class CurriculumItemController extends CommonController
         $routes['add_from_category'] = 'curriculum_item.controller:addFromCategoryAction';
         return $routes ;
     }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'tool/curriculum/item/';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CurriculumItem');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new CurriculumItem();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new CurriculumItemType();
-    }
 }

+ 41 - 86
src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumUserController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\Tool\Curriculum;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Silex\Application;
 use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
 use Symfony\Component\HttpFoundation\Response;
@@ -21,14 +21,51 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class CurriculumUserController extends CommonController
+class CurriculumUserController extends CrudController
 {
+    public function getControllerAlias()
+    {
+        return 'curriculum_user.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'tool/curriculum/user/';
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\CurriculumItemRelUser';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\CurriculumItemRelUserCollectionType';
+    }
+
+    protected function generateDefaultCrudRoutes()
+    {
+        $routes = parent::generateDefaultCrudRoutes();
+        $routes['add_from_category'] = 'curriculum_item.controller:addFromCategoryAction';
+        return $routes;
+    }
+
     /**
      *
      * @Route("/")
      * @Method({"GET"})
      */
-    public function indexAction(Application $app)
+    public function indexAction()
     {
         // @todo Use filters like "after/before|finish" to manage user access
         api_block_anonymous_users();
@@ -118,7 +155,7 @@ class CurriculumUserController extends CommonController
     {
         $request = $this->getRequest();
         $form = $this->get('form.factory')->create($this->getFormType(), $this->getDefaultEntity());
-        $token = $this->get('security')->getToken();
+        $token = $this->getSecurity()->getToken();
         $user = $token->getUser();
 
         if ($request->getMethod() == 'POST') {
@@ -330,73 +367,6 @@ class CurriculumUserController extends CommonController
         return false;
     }
 
-    /**
-    *
-    * @Route("/{id}", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function readAction($id)
-    {
-        return parent::readAction($id);
-    }
-
-    /**
-    * @Route("/add")
-    * @Method({"GET"})
-    */
-    public function addAction()
-    {
-        return parent::addAction();
-    }
-
-    /**
-    *
-    * @Route("/{id}/edit", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function editAction($id)
-    {
-        return parent::editAction($id);
-    }
-
-    /**
-    *
-    * @Route("/{id}/delete", requirements={"id" = "\d+"})
-    * @Method({"GET"})
-    */
-    public function deleteAction($id)
-    {
-        return parent::deleteAction($id);
-    }
-
-    protected function getControllerAlias()
-    {
-        return 'curriculum_user.controller';
-    }
-
-    protected function generateDefaultCrudRoutes()
-    {
-        $routes = parent::generateDefaultCrudRoutes();
-        $routes['add_from_category'] = 'curriculum_item.controller:addFromCategoryAction';
-        return $routes;
-    }
-
-    /**
-    * {@inheritdoc}
-    */
-    protected function getTemplatePath()
-    {
-        return 'tool/curriculum/user/';
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CurriculumItemRelUser');
-    }
-
     private function getCurriculumCategoryRepository()
     {
         return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CurriculumCategory');
@@ -407,19 +377,4 @@ class CurriculumUserController extends CommonController
         return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CurriculumItem');
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new CurriculumItemRelUser();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getFormType()
-    {
-        return new CurriculumItemRelUserCollectionType();
-    }
 }

+ 3 - 2
src/ChamiloLMS/Controller/ExerciseController.php → src/ChamiloLMS/Controller/Tool/Exercise/ExerciseController.php

@@ -1,8 +1,9 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-namespace ChamiloLMS\Controller;
+namespace ChamiloLMS\Controller\Tool\Exercise;
 
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\Request;
@@ -14,7 +15,7 @@ use \ChamiloSession as Session;
  * @package ChamiloLMS.Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class ExerciseController extends CommonController
+class ExerciseController extends BaseController
 {
 
     public function dashboardAction(Application $app, $exerciseId)

+ 29 - 23
src/ChamiloLMS/Controller/Tool/Introduction/IntroductionController.php

@@ -4,19 +4,41 @@
 namespace ChamiloLMS\Controller\Tool\Introduction;
 
 use ChamiloLMS\Entity\CToolIntro;
-use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\CrudController;
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
 /**
  * Class IntroductionToolController
- * @package ChamiloLMS\Controller
+ * @package ChamiloLMS\Controller\Tool\Introduction
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class IntroductionController extends CommonController
+class IntroductionController extends CrudController
 {
+    public function getClass()
+    {
+        return 'ChamiloLMS\Entity\CToolIntro';
+    }
+
+    public function getType()
+    {
+        return 'ChamiloLMS\Form\BranchType';
+    }
+
+    public function getControllerAlias()
+    {
+        return 'branch.controller';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTemplatePath()
+    {
+        return 'admin/administrator/branches/';
+    }
+
     /**
      * @Route("/edit/{tool}")
      * @Method({"GET"})
@@ -36,14 +58,14 @@ class IntroductionController extends CommonController
 
         $url = $this->generateUrl(
             'introduction.controller:editAction',
-            array('tool' => $tool, 'course' => api_get_course_id())
+            array('tool' => $tool, 'courseCode' => api_get_course_id())
         );
 
         $form = $this->getForm($url, $tool);
 
         if ($form->validate()) {
             $values  = $form->exportValues();
-			$content = $values['content'];
+            $content = $values['content'];
 
             $sql = "REPLACE $TBL_INTRODUCTION
                     SET c_id = $courseId,
@@ -98,7 +120,7 @@ class IntroductionController extends CommonController
 
         $url = $this->generateUrl(
             'introduction.controller:editAction',
-            array('tool' => $tool, 'course' => api_get_course_id())
+            array('tool' => $tool, 'courseCode' => api_get_course_id())
         );
 
         $form = $this->getForm($url, $tool);
@@ -135,20 +157,4 @@ class IntroductionController extends CommonController
         return $form;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function getRepository()
-    {
-        return $this->get('orm.em')->getRepository('ChamiloLMS\Entity\CToolIntro');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function getNewEntity()
-    {
-        return new CToolIntro();
-    }
-
 }

+ 4 - 3
src/ChamiloLMS/Controller/LearnpathController.php → src/ChamiloLMS/Controller/Tool/LearningPath/LearningPathController.php

@@ -1,17 +1,18 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-namespace ChamiloLMS\Controller;
+namespace ChamiloLMS\Controller\Tool\LearningPath;
 
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\HttpFoundation\Response;
 
 /**
- * Class LearnpathController
+ * Class LearningPathController
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class LearnpathController
+class LearningPathController extends BaseController
 {
     /**
      * Index

+ 185 - 0
src/ChamiloLMS/Controller/ToolBaseController.php

@@ -0,0 +1,185 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace ChamiloLMS\Controller;
+
+use ChamiloLMS\Controller\BaseController;
+use Knp\Menu\FactoryInterface as MenuFactoryInterface;
+use Knp\Menu\ItemInterface as MenuItemInterface;
+use Knp\Menu\Renderer\ListRenderer;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Each entity controller must extends this class.
+ *
+ * @abstract
+ */
+abstract class ToolBaseController extends BaseController
+{
+    /**
+     * @param $action
+     * @param MenuItemInterface $menu
+     * @return MenuItemInterface
+     */
+    public function buildBreadcrumbs($action, MenuItemInterface $menu = null)
+    {
+        if (!$menu) {
+            $menu = $this->getHomeBreadCrumb();
+        }
+
+        // Tool home
+        $menu->addChild(
+            $this->trans($this->getClassnameLabel()),
+            array(
+                'uri' => $this->generateControllerUrl(
+                    'indexAction',
+                    array(
+                        'courseCode' => $this->getCourse()->getCode()
+                    )
+                )
+            )
+        );
+
+        $action = str_replace(
+            array($this->getControllerAlias().':', 'Action'),
+            '',
+            $action
+        );
+
+        switch ($action) {
+            case 'add':
+            case 'edit':
+                $menu->addChild(
+                    $this->trans($this->getClassnameLabel().ucfirst($action))
+                    //array('uri' => $this->generateControllerUrl($action.'Action'))
+                );
+                break;
+        }
+
+        return $menu;
+    }
+
+    /**
+     * Converts string 'ChamiloLMS\Controller\Tool\CourseHome\CourseHomeController' into
+     * 'tool/course_home'
+     */
+    public function getTemplatePath()
+    {
+        $parts = $this->getClassParts();
+
+        $newPath = array();
+        foreach ($parts as $part) {
+            if (in_array($part, array('chamilo_lms', 'controller')) ||
+                strpos($part, '_controller') > 0
+            ) {
+                continue;
+            }
+            $newPath[] = $part;
+        }
+
+        $template = implode('/', $newPath);
+        return str_replace('_controller', '', $template);
+    }
+
+    /**
+     * Before middleware for the ToolBaseController
+     */
+    public function before(Request $request)
+    {
+        $cidReset = $this->get('cidReset');
+
+        $cidReq = $request->get('cidReq');
+
+        if (empty($cidReq)) {
+            $cidReq = $request->get('courseCode');
+        }
+
+        $sessionId = $request->get('id_session');
+        $groupId   = $request->get('gidReq');
+
+        $tempCourseId  = api_get_course_id();
+        $tempGroupId   = api_get_group_id();
+        $tempSessionId = api_get_session_id();
+
+        $courseReset = false;
+        if ((!empty($cidReq) && $tempCourseId != $cidReq) || empty($tempCourseId) || empty($tempCourseId) == -1) {
+            $courseReset = true;
+        }
+
+        if (isset($cidReset) && $cidReset == 1) {
+            $courseReset = true;
+        }
+
+        $this->getSessionHandler()->set('courseReset', $courseReset);
+
+        $groupReset = false;
+        if ($tempGroupId != $groupId || empty($tempGroupId)) {
+            $groupReset = true;
+        }
+
+        $sessionReset = false;
+        if ($tempSessionId != $sessionId || empty($tempSessionId)) {
+            $sessionReset = true;
+        }
+        /*
+            $app['monolog']->addDebug('Start');
+            $app['monolog']->addDebug($courseReset);
+            $app['monolog']->addDebug($cidReq);
+            $app['monolog']->addDebug($tempCourseId);
+            $app['monolog']->addDebug('End');
+        */
+
+        if ($courseReset) {
+
+            if (!empty($cidReq) && $cidReq != -1) {
+                $courseInfo = api_get_course_info($cidReq, true, true);
+
+                if (!empty($courseInfo)) {
+                    $courseCode = $courseInfo['code'];
+                    $courseId   = $courseInfo['real_id'];
+
+                    $this->getSessionHandler()->set('_real_cid', $courseId);
+                    $this->getSessionHandler()->set('_cid', $courseCode);
+                    $this->getSessionHandler()->set('_course', $courseInfo);
+
+                } else {
+                    $this->abort(404, $this->trans('Course not available'));
+                }
+            } else {
+                $this->getSessionHandler()->remove('_real_cid');
+                $this->getSessionHandler()->remove('_cid');
+                $this->getSessionHandler()->remove('_course');
+            }
+        }
+
+        $courseCode = api_get_course_id();
+
+        if (!empty($courseCode) && $courseCode != -1) {
+            //$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
+            $time = api_get_utc_datetime();
+            $sql = "UPDATE course SET last_visit= '$time' WHERE code='$courseCode'";
+            $this->getDatabase()->query($sql);
+        }
+
+        if ($sessionReset) {
+            $this->getSessionHandler()->remove('session_name');
+            $this->getSessionHandler()->remove('id_session');
+
+            if (!empty($sessionId)) {
+                $sessionInfo = api_get_session_info($sessionId);
+                if (empty($sessionInfo)) {
+                    $this->abort(404, $this->trans('Session not available'));
+                } else {
+                    $this->getSessionHandler()->set('id_session', $sessionId);
+                }
+            }
+        }
+
+        if ($groupReset) {
+            $this->getSessionHandler()->remove('_gid');
+            if (!empty($groupId)) {
+                $this->getSessionHandler()->set('_gid', $groupId);
+            }
+        }
+    }
+}

+ 3 - 3
src/ChamiloLMS/Controller/User/ProfileController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Controller\User;
 
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\BaseController;
 use Silex\Application;
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
@@ -14,7 +14,7 @@ use Symfony\Component\HttpFoundation\Response;
  * Class ProfileController
  * @package ChamiloLMS\Controller
  */
-class ProfileController extends CommonController
+class ProfileController extends BaseController
 {
     /**
      * @Route("/{username}")
@@ -76,7 +76,7 @@ class ProfileController extends CommonController
     /**
      * {@inheritdoc}
      */
-    protected function getTemplatePath()
+    public function getTemplatePath()
     {
         return 'user/';
     }

+ 3 - 3
src/ChamiloLMS/Controller/User/UserController.php

@@ -6,7 +6,7 @@ namespace ChamiloLMS\Controller\User;
 use Silex\Application;
 
 use Symfony\Component\HttpFoundation\Response;
-use ChamiloLMS\Controller\CommonController;
+use ChamiloLMS\Controller\BaseController;
 use Symfony\Component\Routing\Annotation\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 
@@ -16,7 +16,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  * @package ChamiloLMS\Controller
  * @author Julio Montoya <gugli100@gmail.com>
  */
-class UserController extends CommonController
+class UserController extends BaseController
 {
     /**
      * @Route("/me")
@@ -48,4 +48,4 @@ class UserController extends CommonController
     {
         return 'user/';
     }
-}
+}

+ 0 - 116
src/ChamiloLMS/Controller/UserPortalController.php

@@ -1,116 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-namespace ChamiloLMS\Controller;
-
-use Silex\Application;
-use \ChamiloSession as Session;
-use Symfony\Component\HttpFoundation\Response;
-
-/**
- * Class UserPortalController
- * @package ChamiloLMS\Controller
- * @todo Improve this class in order to use better helpers and not just call the page_controller service
- * @author Julio Montoya <gugli100@gmail.com>
- */
-class UserPortalController extends CommonController
-{
-    /**
-     * @param Application $app
-     * @param string $type courses|sessions|mycoursecategories
-     * @param string $filter for the userportal courses page. Only works when setting 'history'
-     * @param int $page
-     *
-     * @return Response|void
-     */
-    public function indexAction(Application $app, $type = 'courses', $filter = 'current', $page = 1)
-    {
-        // @todo Use filters like "after/before|finish" to manage user access
-        api_block_anonymous_users();
-
-
-        // Abort request because the user is not allowed here - @todo use filters
-        if ($app['allowed'] == false) {
-            return $app->abort(403, 'Not allowed');
-        }
-
-        // Main courses and session list
-        $items = null;
-        $type = str_replace('/', '', $type);
-
-        /** @var \PageController $pageController */
-        $pageController = $app['page_controller'];
-
-        switch ($type) {
-            case 'sessions':
-                $items = $pageController->returnSessions(api_get_user_id(), $filter, $page);
-                break;
-            case 'sessioncategories':
-                $items = $pageController->returnSessionsCategories(api_get_user_id(), $filter, $page);
-                break;
-            case 'courses':
-                $items = $pageController->returnCourses(api_get_user_id(), $filter, $page);
-                break;
-            case 'mycoursecategories':
-                $items = $pageController->returnMyCourseCategories(api_get_user_id(), $filter, $page);
-                break;
-            case 'specialcourses':
-                $items = $pageController->returnSpecialCourses(api_get_user_id(), $filter, $page);
-                break;
-        }
-
-        //Show the chamilo mascot
-        if (empty($items) && empty($filter)) {
-            $pageController->return_welcome_to_course_block($app['template']);
-        }
-
-        /*
-        $app['my_main_menu'] = function($app) {
-            $menu = $app['knp_menu.factory']->createItem('root');
-            $menu->addChild('Home', array('route' => api_get_path(WEB_CODE_PATH)));
-            return $menu;
-        };
-        $app['knp_menu.menus'] = array('main' => 'my_main_menu');*/
-        $app['template']->assign('content', $items);
-        $pageController->setCourseSessionMenu();
-
-        $pageController->setProfileBlock();
-        $pageController->setUserImageBlock();
-        $pageController->setCourseBlock($filter);
-        $pageController->setSessionBlock();
-        $pageController->return_reservation_block();
-        $pageController->returnNavigationLinks($app['template']->getNavigationLinks());
-
-        $app['template']->assign('search_block', $pageController->return_search_block());
-        $app['template']->assign('classes_block', $pageController->return_classes_block());
-        $pageController->returnSkillsLinks();
-
-        // Deleting the session_id.
-        Session::erase('session_id');
-
-        $response = $app['template']->render_template('userportal/index.tpl');
-
-        return new Response($response, 200, array());
-    }
-
-    /**
-     * Toggle the student view action
-     */
-    public function toggleStudentViewAction(Application $app)
-    {
-        if (!api_is_allowed_to_edit(false, false, false, false)) {
-            return '';
-        }
-
-        /** @var Request $request */
-        $request = $app['request'];
-        $studentView = $request->getSession()->get('studentview');
-        if (empty($studentView) || $studentView == 'studentview') {
-            $request->getSession()->set('studentview', 'teacherview');
-            return 'teacherview';
-        } else {
-            $request->getSession()->set('studentview', 'studentview');
-            return 'studentview';
-        }
-    }
-}

+ 1 - 1
src/ChamiloLMS/Form/BranchType.php

@@ -61,7 +61,7 @@ class BranchType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\BranchSync'
+                'data_class' => 'ChamiloLMS\Entity\BranchSync'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/CourseHomeToolType.php

@@ -37,7 +37,7 @@ class CourseHomeToolType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\CTool'
+                'data_class' => 'ChamiloLMS\Entity\CTool'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/CurriculumCategoryType.php

@@ -53,7 +53,7 @@ class CurriculumCategoryType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\CurriculumCategory'
+                'data_class' => 'ChamiloLMS\Entity\CurriculumCategory'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/CurriculumItemRelUserCollectionType.php

@@ -46,7 +46,7 @@ class CurriculumItemRelUserCollectionType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\CurriculumItem'
+                'data_class' => 'ChamiloLMS\Entity\CurriculumItem'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/CurriculumItemRelUserType.php

@@ -26,7 +26,7 @@ class CurriculumItemRelUserType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\CurriculumItemRelUser',
+                'data_class' => 'ChamiloLMS\Entity\CurriculumItemRelUser',
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/JuryMembersType.php

@@ -46,7 +46,7 @@ class JuryMembersType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\JuryMembers'
+                'data_class' => 'ChamiloLMS\Entity\JuryMembers'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/JuryType.php

@@ -46,7 +46,7 @@ class JuryType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\Jury'
+                'data_class' => 'ChamiloLMS\Entity\Jury'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/JuryUserType.php

@@ -21,7 +21,7 @@ class JuryUserType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\Jury'
+                'data_class' => 'ChamiloLMS\Entity\Jury'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/QuestionScoreNameType.php

@@ -30,7 +30,7 @@ class QuestionScoreNameType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\QuestionScoreName'
+                'data_class' => 'ChamiloLMS\Entity\QuestionScoreName'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/QuestionScoreType.php

@@ -20,7 +20,7 @@ class QuestionScoreType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\QuestionScore'
+                'data_class' => 'ChamiloLMS\Entity\QuestionScore'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/RoleType.php

@@ -21,7 +21,7 @@ class RoleType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\Role'
+                'data_class' => 'ChamiloLMS\Entity\Role'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/SessionPathType.php

@@ -32,7 +32,7 @@ class SessionPathType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\SessionPath'
+                'data_class' => 'ChamiloLMS\Entity\SessionPath'
             )
         );
     }

+ 1 - 1
src/ChamiloLMS/Form/SessionTreeType.php

@@ -68,7 +68,7 @@ class SessionTreeType extends AbstractType
     {
         $resolver->setDefaults(
             array(
-                'data_class' => 'Entity\SessionTree'
+                'data_class' => 'ChamiloLMS\Entity\SessionTree'
             )
         );
     }

+ 4 - 1
src/ChamiloLMS/Framework/Application.php

@@ -62,6 +62,9 @@ class Application extends \Silex\Application
         return array();
     }
 
+    /**
+     * Reads the configuration.php file
+     */
     public function readConfigurationFiles()
     {
         $this->configuration = $this->getConfigurationArrayFromFile();
@@ -70,7 +73,7 @@ class Application extends \Silex\Application
             $config = new Config($this->configuration, true);
             $this->installed = true;
 
-            /** Overwriting paths */
+            /** Overwriting paths if set */
 
             $this['path.data'] = empty($config->get('path.data')) ? $this['path.data'] : $config->get('path.data');
             $this['path.course'] = empty($config->get('path.courses')) ? $this['path.courses'] : $config->get('path.courses');

+ 8 - 13
src/ChamiloLMS/Framework/PageController.php

@@ -3,7 +3,7 @@
 
 namespace ChamiloLMS\Framework;
 
-use Silex\Application;
+use ChamiloLMS\Framework\Application;
 use Pagerfanta\Adapter\FixedAdapter;
 use Pagerfanta\Pagerfanta;
 use Pagerfanta\View\TwitterBootstrapView;
@@ -711,10 +711,8 @@ class PageController
                         ).'?category='.$catLine['code'].'">'.$catLine['name'].'</a>';
                         $htmlListCat .= "</li>";
                         $thereIsSubCat = true;
-                    } /* End changed code to eliminate the (0 courses) after empty categories. */ elseif (api_get_setting(
-                        'show_empty_course_categories'
-                    ) == 'true'
-                    ) {
+                    } elseif (api_get_setting('show_empty_course_categories') == 'true') {
+                        /* End changed code to eliminate the (0 courses) after empty categories. */
                         $htmlListCat .= '<li>';
                         $htmlListCat .= $catLine['name'];
                         $htmlListCat .= "</li>";
@@ -725,9 +723,9 @@ class PageController
                     if (api_get_setting('show_back_link_on_top_of_tree') == 'true') {
                         $htmlTitre .= '<a href="'.api_get_self().'">&lt;&lt; '.get_lang('BackToHomePage').'</a>';
                     }
-                    if (!is_null($catLine['parent_id']) || (api_get_setting(
-                        'show_back_link_on_top_of_tree'
-                    ) != 'true' && !is_null($catLine['code']))
+                    if (!is_null($catLine['parent_id']) ||
+                        (api_get_setting('show_back_link_on_top_of_tree') != 'true' &&
+                        !is_null($catLine['code']))
                     ) {
                         $htmlTitre .= '<a href="'.api_get_self(
                         ).'?category='.$catLine['parent_id'].'">&lt;&lt; '.get_lang('Up').'</a>';
@@ -848,7 +846,7 @@ class PageController
                     // We display a subscription link if:
                     // 1. it is allowed to register for the course and if the course is not already in the courselist of the user and if the user is identiefied
                     // 2.
-                    if ($user_identified && !key_exists($course['code'], $courses_of_user)) {
+                    if ($user_identified && !array_key_exists($course['code'], $courses_of_user)) {
                         if ($course['subscribe'] == '1') {
                             $courses_list_string .= '<form action="main/auth/courses.php?action=subscribe&category='.Security::remove_XSS(
                                 $_GET['category']
@@ -872,10 +870,7 @@ class PageController
             $result .= $courses_list_string;
         }
         if ($category != '') {
-            $result .= '<p><a href="'.api_get_self().'"> '.Display :: return_icon(
-                'back.png',
-                get_lang('BackToHomePage')
-            ).get_lang('BackToHomePage').'</a></p>';
+            $result .= '<p><a href="'.api_get_self().'"> '.Display :: return_icon('back.png', get_lang('BackToHomePage')).get_lang('BackToHomePage').'</a></p>';
         }
 
         return $result;

+ 52 - 28
src/ChamiloLMS/Framework/Template.php

@@ -146,7 +146,9 @@ class Template
      */
     public function setBreadcrumb($breadCrumb)
     {
-        if (isset($this->app['breadcrumb']) && !empty($this->app['breadcrumb'])) {
+        if (isset($this->app['breadcrumb']) &&
+            !empty($this->app['breadcrumb'])
+        ) {
             if (empty($breadCrumb)) {
                 $breadCrumb = $this->app['breadcrumb'];
             } else {
@@ -465,6 +467,9 @@ class Template
         }
     }
 
+    /**
+     * Set js files
+     */
     public function setJsFiles()
     {
         $jsFolder = api_get_path(WEB_LIBRARY_JS_PATH);
@@ -497,7 +502,10 @@ class Template
 
         if (api_is_global_chat_enabled()) {
             //Do not include the global chat in LP
-            if ($this->show_learnpath == false && $this->show_footer == true && $this->app['template.hide_global_chat'] == false) {
+            if ($this->show_learnpath == false &&
+                $this->show_footer == true &&
+                $this->app['template.hide_global_chat'] == false
+            ) {
                 $jsFiles[] = $jsFolder.'chat/js/chat.js';
             }
         }
@@ -522,7 +530,7 @@ class Template
      */
     public function getResources()
     {
-       return $this->resources;
+        return $this->resources;
     }
 
     /**
@@ -554,27 +562,27 @@ class Template
             switch($type) {
                 case 'js':
                     if ($this->disableJsAndCss == false) {
-                        foreach($resources as $resource) {
+                        foreach ($resources as $resource) {
                             $resourceToString .= api_get_js_simple($resource);
                         }
                     }
                     break;
                 case 'css':
                     if ($this->disableJsAndCss == false) {
-                        foreach($resources as $resource) {
+                        foreach ($resources as $resource) {
                             $resourceToString .= api_get_css($resource);
                         }
                     }
                     break;
                 case 'string':
                     if ($this->disableJsAndCss == false) {
-                        foreach($resources as $resource) {
+                        foreach ($resources as $resource) {
                             $resourceToString .= $resource;
                         }
                     }
                     break;
                 case 'no_js_css':
-                    foreach($resources as $resource) {
+                    foreach ($resources as $resource) {
                         $resourceToString .= $resource;
                     }
                     break;
@@ -714,9 +722,11 @@ class Template
 
         // Breadcrumb
         if ($this->loadBreadcrumb) {
-            $this->loadBreadcrumbToTemplate();
+            //$this->loadBreadcrumbToTemplate();
         }
 
+        //$this->app['new_breadcrumb'] =
+
         // Extra content
         $extra_header = null;
         if (!api_is_platform_admin()) {
@@ -728,13 +738,13 @@ class Template
     /**
      *
      */
-    public function loadBreadcrumbToTemplate()
+    public function getBreadCrumbLegacyArray()
     {
         if (api_get_setting('breadcrumb_navigation_display') == 'false') {
             return;
         }
-        $breadcrumb = $this->returnBreadcrumb();
-        $this->assign('breadcrumb', $breadcrumb);
+
+        return $this->returnBreadcrumb();
     }
 
     /**
@@ -990,7 +1000,11 @@ class Template
     public function renderTemplate($template, $elements = array())
     {
         $this->parseResources();
-        return $this->app['twig']->render($this->app['template_style'].'/'.$template, $elements);
+
+        return $this->app['twig']->render(
+            $this->app['template_style'].'/'.$template,
+            $elements
+        );
     }
 
     /**
@@ -1076,7 +1090,7 @@ class Template
                         $role = 'administrator';
                     }
                     if ($role == 'ROLE_QUESTION_MANAGER') {
-                        $role = 'QUESTIONMANAGER';
+                        $role = 'QUESTION_MANAGER';
                     }
                     $stripRole = strtolower(str_replace('ROLE_', '', $role));
                     $roleTemplate[] = $stripRole;
@@ -1369,9 +1383,6 @@ class Template
         $session_name = api_get_session_name($session_id);
         $_course = api_get_course_info();
 
-        /*  Plugins for banner section */
-        $web_course_path = $this->app['path.data'];
-
         /* If the user is a coach he can see the users who are logged in its session */
         $navigation = array();
 
@@ -1381,40 +1392,49 @@ class Template
         $my_session_name = is_null($session_name) ? '' : '&nbsp;('.$session_name.')';
 
         if (!empty($_course) && !isset($_GET['hide_course_breadcrumb'])) {
-
-            $navigation_item['url'] = $web_course_path.$_course['path'].'/index.php'.(!empty($session_id) ? '?id_session='.$session_id : '');
+            $navigation_item['url'] = $this->urlGenerator->generate(
+                'course_home.controller:indexAction',
+                array('courseCode' => $_course['code'], 'sessionId' => $session_id)
+            );
+            //$navigation_item['url'] = $web_course_path.$_course['path'].'/index.php'.(!empty($session_id) ? '?id_session='.$session_id : '');
             $course_title = Text::cut($_course['name'], MAX_LENGTH_BREADCRUMB);
 
             switch (api_get_setting('breadcrumbs_course_homepage')) {
                 case 'get_lang':
-                    $navigation_item['title'] = Display::img(
+                    $navigation_item['title'] = /*Display::img(
                         api_get_path(WEB_CSS_PATH).'home.png',
                         get_lang('CourseHomepageLink')
-                    ).' '.get_lang('CourseHomepageLink');
+                    ).' '.*/
+                        get_lang('CourseHomepageLink');
                     break;
                 case 'course_code':
-                    $navigation_item['title'] = Display::img(
+                    $navigation_item['title'] = /*Display::img(
                         api_get_path(WEB_CSS_PATH).'home.png',
                         $_course['official_code']
-                    ).' '.$_course['official_code'];
+                    ).' '.
+                        */
+                        $_course['official_code'];
                     break;
                 case 'session_name_and_course_title':
-                    $navigation_item['title'] = Display::img(
+                    $navigation_item['title'] = /*Display::img(
                         api_get_path(WEB_CSS_PATH).'home.png',
                         $_course['name'].$my_session_name
-                    ).' '.$course_title.$my_session_name;
+                    ).' '.*/
+                        $course_title.$my_session_name;
                     break;
                 default:
                     if (api_get_session_id() != -1) {
-                        $navigation_item['title'] = Display::img(
+                        $navigation_item['title'] = /*Display::img(
                             api_get_path(WEB_CSS_PATH).'home.png',
                             $_course['name'].$my_session_name
-                        ).' '.$course_title.$my_session_name;
+                        ).' '.*/
+                            $course_title.$my_session_name;
                     } else {
-                        $navigation_item['title'] = Display::img(
+                        $navigation_item['title'] = /*Display::img(
                             api_get_path(WEB_CSS_PATH).'home.png',
                             $_course['name']
-                        ).' '.$course_title;
+                        ).' '.*/
+                            $course_title;
                     }
                     break;
             }
@@ -1469,6 +1489,9 @@ class Template
         $counter = 0;
         $navigation[] = array('url' => '#', 'title' => strip_tags($this->title));
 
+
+        return $navigation;
+
         foreach ($navigation as $index => $navigation_info) {
             if (!empty($navigation_info['title'])) {
                 if ($navigation_info['url'] == '#') {
@@ -1480,6 +1503,7 @@ class Template
             }
         }
 
+
         $html = '';
         if (!empty($final_navigation)) {
             $lis = '';

+ 14 - 0
src/ChamiloLMS/Framework/Widget.php

@@ -0,0 +1,14 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace ChamiloLMS\Framework;
+
+/**
+ * Class Widget
+ * @package ChamiloLMS\Framework
+ * @author Julio Montoya <gugli100@gmail.com>
+ */
+class Widget
+{
+
+}

+ 51 - 5
src/ChamiloLMS/Provider/ReflectionControllerProvider.php

@@ -15,9 +15,12 @@ use Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader;
 
 use Doctrine\Common\Annotations\AnnotationReader;
 use ChamiloLMS\Middleware\CourseMiddleware;
+use Symfony\Component\HttpKernel\KernelEvents;
 
 /**
  * Class ReflectionControllerProvider
+ * Parses the controllers classes in order to transform the
+ * @route and @method annotations into routes.
  * @package ChamiloLMS\Provider
  */
 class ReflectionControllerProvider implements ControllerProviderInterface
@@ -58,6 +61,10 @@ class ReflectionControllerProvider implements ControllerProviderInterface
 
         $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
 
+        /*$app['dispatcher']->addListener(KernelEvents::REQUEST, function() use ($path) {
+            unlink($path);
+        });*/
+
         foreach ($methods as $method) {
             $methodName = $method->getName();
             $controllerName = $this->controllerName.':'.$methodName;
@@ -79,20 +86,49 @@ class ReflectionControllerProvider implements ControllerProviderInterface
                 $methodsToString = implode('|', $methodObject->getMethods());
             }
 
+            /*$print = false;
+            if ($controllerName == 'course_home.controller:indexAction') {
+                $print = true;
+                //var_dump($routeObjects);
+            }*/
+
             /** @var Route $routeObject */
-            foreach ($routeObjects as $routeObject) {
+            $routes = array();
 
+            foreach ($routeObjects as $routeObject) {
                 if ($routeObject && is_a($routeObject, 'Symfony\Component\Routing\Annotation\Route')) {
-                    $match = $controllers->match($routeObject->getPath(), $controllerName, $methodsToString);
-                    // Setting requirements
+                    $name = $routeObject->getName();
+
+                    $routeName = $controllerName;
+                    // If route already exists add a "_XX" where XX is an int.
+                    $bindName = $controllerName;
+                    if (in_array($bindName, $routes)) {
+                        $counter = 1;
+                        while (in_array($bindName, $routes)) {
+                            $bindName = $controllerName.'_'.$counter;
+                            $counter++;
+                        }
+                    }
+
+                    $match = $controllers->match(
+                        $routeObject->getPath(),
+                        $routeName
+                    )
+                        ->method($methodsToString)
+                        ->before($this->controllerName . ':before');
+
+                    $routes[] = $bindName;
+
+                    // Setting requirements.
                     $req = $routeObject->getRequirements();
+
                     if (!empty($req)) {
                         foreach ($req as $key => $value) {
                             $match->assert($key, $value);
                         }
                     }
 
-                    // Setting defaults
+                    // Setting defaults.
                     $defaults = $routeObject->getDefaults();
                     if (!empty($defaults)) {
                         foreach ($defaults as $key => $value) {
@@ -100,10 +136,20 @@ class ReflectionControllerProvider implements ControllerProviderInterface
                         }
                     }
 
-                    $match->bind($controllerName);
+                    // Setting options
+                    //$options = $routeObject->getOptions();
+
+                    // Adding bind
+                    $match->bind($bindName);
+
+                    // Adding alias if exists.
+                    if (!empty($name)) {
+                        $match->bind($name);
+                    }
                 }
             }
         }
+
         return $controllers;
     }
 }

+ 2 - 2
src/ChamiloLMS/Resources/views/default/admin/administrator/branches/list.tpl

@@ -1,7 +1,7 @@
 {% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
 {% block content %}
-    <a href="{{ url(links.create_link) }}">
-        Add
+    <a class="btn btn-default" href="{{ url(links.create_link) }}">
+        {{ 'Add' | trans }}
     </a>
     {{ tree }}
 {% endblock %}

+ 2 - 2
src/ChamiloLMS/Resources/views/default/admin/administrator/role/list.tpl

@@ -1,5 +1,5 @@
 {% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
 {% block content %}
-    {% import app.template_style ~ "/crud_macros/simple_crud.tpl" as actions %}
-    {{ actions.list(items, links) }}
+{% import app.template_style ~ "/crud_macros/simple_crud.tpl" as actions %}
+{{ actions.list(items, links) }}
 {% endblock %}

+ 1 - 0
src/ChamiloLMS/Resources/views/default/admin/index.tpl

@@ -6,6 +6,7 @@
                 {% if is_granted('ROLE_ADMIN') %}
                     {# Skip session admin #}
                     {% if (role != 'session_manager') %}
+                        {{ role | var_dump }}
                         {% include app.template_style ~ "/admin/" ~ role ~ "/role_index.tpl" %}
                     {% endif %}
                 {% else %}

+ 0 - 0
src/ChamiloLMS/Resources/views/default/admin/questionmanager/edit_category.tpl → src/ChamiloLMS/Resources/views/default/admin/question_manager/edit_category.tpl


+ 0 - 0
src/ChamiloLMS/Resources/views/default/admin/questionmanager/edit_question.tpl → src/ChamiloLMS/Resources/views/default/admin/question_manager/edit_question.tpl


+ 2 - 2
src/ChamiloLMS/Resources/views/default/admin/questionmanager/question_categories.tpl → src/ChamiloLMS/Resources/views/default/admin/question_manager/question_categories.tpl

@@ -2,9 +2,9 @@
 {% block left_column %}
     <script>
         function loadQuestions(id) {
-            var categoryUrl = '{{ url('admin_questions_get_categories', {id : ':s'}) }}';
+            var categoryUrl = '{{ url('question_manager.controller:getCategoriesAction', {id : ':s'}) }}';
             categoryUrl = categoryUrl.replace(':s', id);
-            var questionContentUrl = '{{ url('admin_get_questions_by_category', {categoryId : ':s'}) }}';
+            var questionContentUrl = '{{ url('question_manager.controller:getQuestionsByCategoryAction', {categoryId : ':s'}) }}';
             questionContentUrl = questionContentUrl.replace(':s', id);
             $('.questions').load(questionContentUrl);
             var parent = $('.load_categories li #'+id).parent();

+ 1 - 1
src/ChamiloLMS/Resources/views/default/admin/questionmanager/questionmanager.tpl → src/ChamiloLMS/Resources/views/default/admin/question_manager/questionmanager.tpl

@@ -1,4 +1,4 @@
 {% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
 {% block content %}
-{% include app.template_style ~ '/admin/questionmanager/role_index.tpl' %}
+{% include app.template_style ~ '/admin/question_manager/role_index.tpl' %}
 {% endblock %}

+ 2 - 2
src/ChamiloLMS/Resources/views/default/admin/questionmanager/questions.tpl → src/ChamiloLMS/Resources/views/default/admin/question_manager/questions.tpl

@@ -124,12 +124,12 @@
         <h3>{{  category.title }}
 
         {% if category.cId == 0 %}
-            <a href="{{ url('admin_category_edit', {id : category.iid}) }}">
+            <a href="{{ url('question_manager.controller:editCategoryAction', {id : category.iid}) }}">
                 <img src="{{ "edit.png"|icon(22) }}">
             </a>
         {% endif %}
         {% if category_children == 0 %}
-            &nbsp; <a href="{{ url('admin_category_delete', {id : category.iid}) }}">
+            &nbsp; <a href="{{ url('question_manager.controller:deleteCategoryAction', {id : category.iid}) }}">
                 <img src="{{ "delete.png"|icon(22) }}">
             </a>
         {% endif %}

+ 21 - 0
src/ChamiloLMS/Resources/views/default/admin/question_manager/role_index.tpl

@@ -0,0 +1,21 @@
+<div class="col-md-6">
+    <div class="well_border">
+        <h4>{{ 'Questions' | get_lang }}</h4>
+        <ul>
+            <li>
+                <a href="{{ url('question_manager.controller:getQuestionsAction') }}">
+                {{ 'Questions' | get_lang }}</a>
+            </li>
+            <li>
+                <a href="{{ url('question_manager.controller:newCategoryAction')}}">
+                    {{ 'AddACategory' | get_lang }}
+                </a>
+            </li>
+            <li>
+                <a href="{{ _p.web }}main/exercice/tests_category.php?type=global">
+                    {{ 'ManageQuestionCategories' | get_lang }}
+                </a>
+            </li>
+        </ul>
+    </div>
+</div>

+ 0 - 0
src/ChamiloLMS/Resources/views/default/admin/questionmanager/show_category.tpl → src/ChamiloLMS/Resources/views/default/admin/question_manager/show_category.tpl


+ 0 - 13
src/ChamiloLMS/Resources/views/default/admin/questionmanager/role_index.tpl

@@ -1,13 +0,0 @@
-<div class="col-md-6">
-    <div class="well_border">
-        <h4>{{ 'Questions'  | get_lang }}</h4>
-        <ul>
-            <li>
-                <a href="{{ url('admin_questions') }}">
-                {{ 'Questions' | get_lang }}</a>
-            </li>
-            <li><a href="{{ url('admin_category_new')}}">{{ 'AddACategory' | get_lang }}</a></li>
-            <li><a href="{{ _p.web }}main/exercice/tests_category.php?type=global">{{ 'ManageQuestionCategories' | get_lang }}</a></li>
-        </ul>
-    </div>
-</div>

+ 30 - 17
src/ChamiloLMS/Resources/views/default/crud_macros/simple_crud.tpl

@@ -1,7 +1,9 @@
 {% macro list(items, links) %}
-    <a href="{{ url(links.create_link) }}">
-        {{ 'Add' |trans }}
-    </a>
+    <div class="btn-group">
+        <a class="btn btn-default" href="{{ url(links.create_link) }}">
+            <i class="fa fa-plus"></i> {{ 'Add' |trans }}
+        </a>
+    </div>
     <table class="table">
     {% for item in items %}
         <tr>
@@ -11,18 +13,25 @@
                 </a>
             </td>
             <td>
-                <a class="btn" href="{{ url(links.update_link, { id: item.id }) }}"> {{ 'Edit' |trans }}</a>
-                <a class="btn" href="{{ url(links.delete_link, { id: item.id }) }}"> {{ 'Delete' |trans }}</a>
+                <a class="btn btn-default" href="{{ url(links.update_link, { id: item.id }) }}">
+                    {{ 'Edit' |trans }}
+                </a>
+                <a class="btn btn-danger" href="{{ url(links.delete_link, { id: item.id }) }}">
+                    {{ 'Delete' |trans }}
+                </a>
             </td>
         </tr>
     {% endfor %}
     </table>
+    {{ grid_pagination }}
 {% endmacro %}
 
 {% macro add(form, links) %}
-    <a href="{{ url(links.list_link) }}">
-        {{ 'List' |trans }}
-    </a>
+    <div class="btn-group">
+        <a class="btn btn-default" href="{{ url(links.list_link) }}">
+            <i class="fa fa-list"></i> {{ 'Return to list' |trans }}
+        </a>
+    </div>
     <hr />
     <form action="{{ url(links.create_link) }}" method="post" {{ form_enctype(form) }}>
         {{ form_widget(form) }}
@@ -30,21 +39,25 @@
 {% endmacro %}
 
 {% macro edit(form, links) %}
-    <a href="{{ url(links.list_link) }}">
-        {{ 'List' |trans }}
-    </a>
+    <div class="btn-group">
+        <a class="btn btn-default" href="{{ url(links.list_link) }}">
+            <i class="fa fa-list"></i> {{ 'Return to list' |trans }}
+        </a>
+    </div>
     <form action="{{ url(links.update_link, {id : item.id}) }}" method = "post" {{ form_enctype(form) }}>
         {{ form_widget(form) }}
     </form>
 {% endmacro %}
 
 {% macro read(item, links) %}
-    <a href="{{ url(links.list_link) }}">
-        {{ 'List' |trans }}
-    </a>
-    <a href="{{ url(links.update_link, {id : item.id}) }}">
-        {{ 'Edit' |trans }}
-    </a>
+    <div class="btn-group">
+        <a class="btn btn-default" href="{{ url(links.update_link, {id : item.id}) }}">
+            <i class="fa fa-edit"></i> {{ 'Edit' |trans }}
+        </a>
+        <a class="btn btn-default" href="{{ url(links.list_link) }}">
+            <i class="fa fa-list"></i> {{ 'Return to list' |trans }}
+        </a>
+    </div>
     <h2> {{ item.id  }}</h2>
     <p>{{ item.name }}</p>
 {% endmacro %}

+ 2 - 1
src/ChamiloLMS/Resources/views/default/layout/bread.tpl

@@ -29,6 +29,7 @@
         {% endif %}
     {% endfor %}
 {% endblock %}
+
 {% block label %}
-    {{ item.label }}
+{{ item.label }}
 {% endblock %}

+ 18 - 20
src/ChamiloLMS/Resources/views/default/layout/breadcrumb.tpl

@@ -1,5 +1,4 @@
 {# Breadcrumb #}
-
 {% if app.breadcrumbs %}
     {{ app.breadcrumbs }}
 {% else %}
@@ -7,7 +6,7 @@
     $(document).ready( function() {
         $('.toggle_student_view').on('click', function() {
             $.ajax({
-                url: '{{ url('toggle_student_view') }}',
+                url: '{{ url('index.controller:toggleStudentViewAction') }}',
                 success: function(data) {
                     location.reload();
                 }
@@ -15,25 +14,24 @@
         });
     });
     </script>
-    {% if breadcrumb %}
-        <ul class="breadcrumb">
-            {{ breadcrumb }}
-            {% if ("student_view_enabled" | get_setting) == 'true' %}
-                {% if is_granted('ROLE_TEACHER') and app.session.get('_cid')  %}
-                    <div id="view_as_link" class="pull-right">
-                        {% if app.session.get('studentview') == 'studentview' %}
-                            <a class="btn btn-success btn-xs toggle_student_view" target="_self">
-                                {{ 'StudentView' | trans }}
-                            </a>
-                        {% else %}
-                            <a class="btn btn-default btn-xs toggle_student_view"target="_self">
-                                {{ 'CourseManagerview' | trans }}
-                            </a>
-                        {% endif %}
-                    </div>
+
+    {{ new_breadcrumb }}
+
+    {% if ("student_view_enabled" | get_setting) == 'true' %}
+        {% if is_granted('ROLE_TEACHER') and app.session.get('_cid')  %}
+            <div id="view_as_link" class="pull-right">
+                {% if app.session.get('studentview') == 'studentview' %}
+                    <a class="btn btn-success btn-xs toggle_student_view" target="_self">
+                        {{ 'StudentView' | trans }}
+                    </a>
+                {% else %}
+                    <a class="btn btn-default btn-xs toggle_student_view"target="_self">
+                        {{ 'CourseManagerview' | trans }}
+                    </a>
                 {% endif %}
-            {% endif %}
-        </ul>
+            </div>
+        {% endif %}
     {% endif %}
+
 {% endif %}
 

+ 1 - 1
src/ChamiloLMS/Resources/views/default/layout/menu.tpl

@@ -64,7 +64,7 @@
                         </li>
                     {% endfor %}
                     <li>
-                        <a href=" {{ url('portal_news') }}">
+                        <a href=" {{ url('news.controller:indexAction') }}">
                             {{ 'SeeAllNotifications' | trans }}
                             <i class="fa fa-arrow-right"></i>
                         </a>

+ 3 - 17
src/ChamiloLMS/Resources/views/default/layout/sidebar.tpl

@@ -48,20 +48,6 @@
                     </a>
                 </li>
 
-                <li class="active">
-                    <a href="{{ _p.web_main }}calendar/agenda_js.php?type=personal">
-                        <i class="fa fa-calendar fa-lg"></i>
-                        <span class="text">{{ 'Agenda' | get_lang }}</span>
-                    </a>
-                </li>
-
-                <li class="active">
-                    <a href="{{ _p.web }}main/social/home.php">
-                        <i class="fa fa-user fa-lg"></i>
-                        <span class="text">{{ 'Profile' | get_lang }}</span>
-                    </a>
-                </li>
-
                 <li class="active">
                     <a href="{{ _p.web }}main/social/groups.php">
                         <i class="fa fa-users fa-lg"></i>
@@ -70,9 +56,9 @@
                 </li>
 
                 <li class="active">
-                    <a href="{{ _p.web_main }}mySpace/index.php">
-                        <i class="fa  fa-bar-chart-o fa-lg"></i>
-                        <span class="text">{{ 'Reporting' | get_lang }}</span>
+                    <a href="{{ _p.web }}main/social/groups.php">
+                        <i class="fa fa-users fa-lg"></i>
+                        <span class="text">{{ 'Sessions' | get_lang }}</span>
                     </a>
                 </li>
 

+ 0 - 8
src/ChamiloLMS/Resources/views/default/pages/add.tpl

@@ -1,8 +0,0 @@
-{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
-
-{% block content %}
-<form action="#" method="post">
-    {{ form_widget(form) }}
-    <input class="btn" type="submit" name="submit" value="{{ "Send" | get_lang }}" />
-</form>
-{% endblock %}

+ 0 - 14
src/ChamiloLMS/Resources/views/default/pages/listing.tpl

@@ -1,14 +0,0 @@
-{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
-
-{% block content %}
-    {% for page in pages %}
-        {{ page.title }} -
-        {{ page.slug }} -
-        {{ page.created }} -
-        {{ page.updated }} -
-        <a href="{{ url('edit', {id: page.id}) }}">Edit</a> <a href="{{ url('delete', {id: page.id}) }}">Delete</a>
-        {{ loop.index }}/{{ loop.length }}
-        <br />
-    {% endfor %}
-    {{ pagination }}
-{% endblock %}

+ 0 - 8
src/ChamiloLMS/Resources/views/default/pages/show.tpl

@@ -1,8 +0,0 @@
-{% extends app.template_style ~ '/layout/layout_1_col.tpl' %}
-
-{% block content %}
-    {{ page|var_dump}}
-    {{ page.title }}
-    {{ page.slug }}
-    {{ page.content }}
-{% endblock %}

+ 8 - 26
src/ChamiloLMS/app.php

@@ -36,27 +36,19 @@ Patchwork\Utf8\Bootup::initAll();
 
 $app = new Application();
 
+// Installing Chamilo paths.
 $app->bindInstallPaths(require __DIR__.'/paths.php');
 
+// Reading configuration files.
 $app->readConfigurationFiles();
 
 $alreadyInstalled = $app->isInstalled();
 
-/** End loading config files */
-
-/** Including legacy libs */
 $basePath = $app['path.base'];
 
+/** Including legacy libs */
 require_once $basePath . 'main/inc/lib/api.lib.php';
-
-// Setting $_configuration['url_append']
-/*
-$urlInfo = isset($_configuration['root_web']) ? parse_url($_configuration['root_web']) : null;
-$_configuration['url_append'] = null;
-if (isset($urlInfo['path'])) {
-    $_configuration['url_append'] = '/'.basename($urlInfo['path']);
-}*/
-
+// @todo remove $_configuration['url_append'] calls
 $libPath = $basePath.'/main/inc/lib/';
 
 // Database constants
@@ -70,10 +62,9 @@ require_once $libPath . 'formvalidator/Rule/allowed_tags.inc.php';
 
 $app['app.theme'] = 'chamilo';
 
-// Developer options relies in the configuration.php file
-
-$app['debug'] = isset($_configuration['debug']) ? $_configuration['debug'] : false;
-$app['show_profiler'] = isset($_configuration['show_profiler']) ? $_configuration['show_profiler'] : false;
+// Developer options relies in the configuration.php file.
+$app['debug'] = isset($app->getConfiguration()->debug) ? $app->getConfiguration()->debug : false;
+$app['show_profiler'] = isset($app->getConfiguration()->show_profiler) ? $app->getConfiguration()->show_profiler : false;
 
 // Enables assetic in order to load 1 compressed stylesheet or split files
 //$app['assetic.enabled'] = $app['debug'];
@@ -199,19 +190,10 @@ $app->error(
     }
 );
 
-// Checking if we have a valid language. If not we set it to the platform language.
-$cidReset = null;
+$app['cidReset'] = null;
 
 require_once $app['path.app'].'filters.php';
 
-// The global variable $charset has been defined in a language file too (trad4all.inc.php), this is legacy situation.
-// So, we have to reassign this variable again in order to keep its value right.
-$charset = $charset_initial_value;
-
-// The global variable $text_dir has been defined in the language file trad4all.inc.php.
-// For determing text direction correspondent to the current language we use now information from the internationalization library.
-$text_dir = api_get_text_direction();
-
 /** Setting the is_admin key */
 $app['is_admin'] = false;
 

+ 5 - 3
src/ChamiloLMS/filters.php

@@ -19,7 +19,7 @@ use ChamiloLMS\Entity\User;
 
 /* A "before" middleware allows you to tweak the Request
  * before the controller is executed. */
-
+/** @var ChamiloLMS\Framework\Application $app */
 $app->before(
     function () use ($app) {
         /** @var Request $request */
@@ -31,7 +31,7 @@ $app->before(
             return new RedirectResponse($url);
         }
 
-        // Check data folder
+        // Check data folder.
         if (!is_writable($app['path.data'])) {
             $app->abort(500, "data folder must be writable.");
         }
@@ -41,7 +41,9 @@ $app->before(
             $app->abort(500, "data/temp folder must be writable.");
         }
 
-        // Checking that configuration is loaded
+        //$this->app['new_breadcrumb'] = $this->getBreadcrumbs(null);
+
+        // Checking that configuration is loaded.
         $configuration = $app->getConfigurationArray();
         if (!isset($configuration)) {
             $app->abort(500, '$configuration array must be set in the configuration.php file.');

+ 1 - 0
src/ChamiloLMS/paths.php

@@ -10,6 +10,7 @@ return array(
     'config' => __DIR__.'/../../config',
 
     // Can be overwritten in configuration.php
+
     /* data */
     'data' => __DIR__.'/../../data',
     /* temp */

+ 52 - 169
src/ChamiloLMS/routes.php

@@ -83,108 +83,6 @@ $checkLogin = function (Request $request) use ($app) {
     }
 };
 
-/** Setting course session and group global values */
-$settingCourseConditions = function (Request $request) use ($cidReset, $app) {
-
-    $cidReq    = $request->get('cidReq');
-    $sessionId = $request->get('id_session');
-    $groupId   = $request->get('gidReq');
-
-    $tempCourseId  = api_get_course_id();
-    $tempGroupId   = api_get_group_id();
-    $tempSessionId = api_get_session_id();
-
-    $courseReset = false;
-    if ((!empty($cidReq) && $tempCourseId != $cidReq) || empty($tempCourseId) || empty($tempCourseId) == -1) {
-        $courseReset = true;
-    }
-
-    if (isset($cidReset) && $cidReset == 1) {
-        $courseReset = true;
-    }
-
-    Session::write('courseReset', $courseReset);
-
-    $groupReset = false;
-    if ($tempGroupId != $groupId || empty($tempGroupId)) {
-        $groupReset = true;
-    }
-
-    $sessionReset = false;
-    if ($tempSessionId != $sessionId || empty($tempSessionId)) {
-        $sessionReset = true;
-    }
-    /*
-        $app['monolog']->addDebug('Start');
-        $app['monolog']->addDebug($courseReset);
-        $app['monolog']->addDebug($cidReq);
-        $app['monolog']->addDebug($tempCourseId);
-        $app['monolog']->addDebug('End');
-    */
-
-    if ($courseReset) {
-        if (!empty($cidReq) && $cidReq != -1) {
-            $courseInfo = api_get_course_info($cidReq, true, true);
-
-            if (!empty($courseInfo)) {
-                $courseCode = $courseInfo['code'];
-                $courseId   = $courseInfo['real_id'];
-
-                Session::write('_real_cid', $courseId);
-                Session::write('_cid', $courseCode);
-                Session::write('_course', $courseInfo);
-
-            } else {
-                $app->abort(404, 'Course not available');
-            }
-        } else {
-            Session::erase('_real_cid');
-            Session::erase('_cid');
-            Session::erase('_course');
-        }
-    }
-
-    $courseCode = api_get_course_id();
-
-    if (!empty($courseCode) && $courseCode != -1) {
-        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
-        $time = api_get_utc_datetime();
-        $sql = "UPDATE $tbl_course SET last_visit= '$time' WHERE code='$courseCode'";
-        Database::query($sql);
-    }
-
-    if ($sessionReset) {
-        Session::erase('session_name');
-        Session::erase('id_session');
-
-        if (!empty($sessionId)) {
-            $sessionInfo = api_get_session_info($sessionId);
-            if (empty($sessionInfo)) {
-                $app->abort(404, 'Session not available');
-            } else {
-                Session::write('id_session', $sessionId);
-            }
-        }
-    }
-
-    if ($groupReset) {
-        Session::erase('_gid');
-        if (!empty($groupId)) {
-            Session::write('_gid', $groupId);
-        }
-    }
-
-    /*if (!isset($_SESSION['login_as'])) {
-        $userId = api_get_user_id();
-
-        // Course login
-        if (isset($userId)) {
-            //@todo move to
-            //event_course_login(api_get_course_int_id(), $userId, api_get_session_id());
-        }
-    }*/
-};
-
 /** Only course admin has access. */
 $userCourseAdmin = function (Request $request) use ($app) {
     if (api_is_allowed_to_edit()) {
@@ -479,37 +377,38 @@ $removeCidResetDependingOfSection = function (Request $request) use ($app, $remo
 };
 
 /** "/" and "/index" paths */
-$app->match('/', 'index.controller:indexAction', 'GET')
+/*$app->match('/', 'index.controller:indexAction', 'GET')
     ->assert('type', '.+') //allowing slash "/"
     ->before($removeCidReset)
     ->after($afterLogin)
     ->bind('root')
-;
+;*/
 
+/*
 $app->match('/index', 'index.controller:indexAction', 'GET')
     ->before($removeCidReset)
     ->after($afterLogin)
-    ->bind('index');
+    ->bind('index');*/
 
 /** User portal */
-$app->get('/userportal', 'userPortal.controller:indexAction')
+/*$app->get('/userportal', 'userPortal.controller:indexAction')
     ->before($userIsLoggedIn)
-    ->before($removeCidReset);
+    ->before($removeCidReset);*/
 
-$app->get('/toggleStudentView', 'userPortal.controller:toggleStudentViewAction')->bind('toggle_student_view');
+//$app->get('/toggleStudentView', 'userPortal.controller:toggleStudentViewAction')->bind('toggle_student_view');
 
-$app->get('/userportal/{type}/{filter}/{page}', 'userPortal.controller:indexAction')
+/*$app->get('/userportal/{type}/{filter}/{page}', 'userPortal.controller:indexAction')
     ->before($userIsLoggedIn)
     ->before($removeCidReset)
     ->value('type', 'courses') //default values
     ->value('filter', 'current')
     ->value('page', '1')
-    ->bind('userportal');
+    ->bind('userportal');*/
 
 /** Legacy wrapper */
 $app->match('/main/{file}', 'legacy.controller:classicAction', 'GET|POST')
     ->before($removeCidResetDependingOfSection)
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($checkLogin)
     ->before(function () use ($app) {
         // Do not load breadcrumbs
@@ -524,7 +423,7 @@ $app->match('/login', 'index.controller:loginAction', 'GET|POST')
     ->bind('login');
 
 /** Course home instead of courses/MATHS the new URL is web/courses/MATHS  */
-$app->match('/courses/{cidReq}/{id_session}/', 'course_home.controller:indexAction', 'GET|POST')
+/*$app->match('/courses/{cidReq}/{id_session}/', 'course_home.controller:indexAction', 'GET|POST')
     ->assert('id_session', '\d+')
     ->assert('type', '.+')
     ->before($settingCourseConditions)
@@ -536,13 +435,13 @@ $app->match('/courses/{cidReq}', 'course_home.controller:indexAction', 'GET|POST
     ->assert('type', '.+')
     ->before($settingCourseConditions)
     ->before($userPermissionsInsideACourse)
-    ->before($checkLogin);
+    ->before($checkLogin);*/
 
 // @todo this is the same as above but with out slash (otherwise we will have an httpexception)
-$app->match('/courses/{cidReq}/', 'course_home.controller:indexAction', 'GET|POST')
+/*$app->match('/courses/{cidReq}/', 'course_home.controller:indexAction', 'GET|POST')
     ->assert('type', '.+')
     ->before($settingCourseConditions)
-    ->before($userPermissionsInsideACourse);
+    ->before($userPermissionsInsideACourse);*/
 
 /** Course documents */
 $app->get('/data/courses/{courseCode}/document/{file}', 'index.controller:getDocumentAction')
@@ -562,16 +461,9 @@ $app->get('/data/courses/{courseCode}/upload/{file}', 'index.controller:getCours
     ->assert('type', '.+')
     ->bind('getCourseUploadFileAction');
 
-/** Certificates */
-$app->match('/certificates/{id}', 'certificate.controller:indexAction', 'GET');
-
-/** Portal news */
-$app->match('/news/{id}', 'news.controller:indexAction', 'GET')
-    ->bind('portal_news_per_id');
-
 /** Portal news */
-$app->match('/news', 'news.controller:newsAction', 'GET')
-    ->bind('portal_news');
+/*$app->match('/news', 'news.controller:newsAction', 'GET')
+    ->bind('portal_news');*/
 
 /** LP controller (subscribe users to a LP) */
 $app->match('/learnpath/subscribe_users/{lpId}', 'learnpath.controller:indexAction', 'GET|POST')
@@ -602,20 +494,8 @@ $app->get('/data/upload/groups/{groupId}/{file}', 'index.controller:getGroupFile
     ->assert('file', '.+')
     ->assert('type', '.+');
 
-/** Admin */
-$app->get('/admin/dashboard', 'index.controller:dashboardAction')
-    ->assert('type', '.+')
-    ->bind('admin_dashboard');
-
 /** Question manager - admin */
-$app->get('/admin/questionmanager', 'question_manager.controller:questionManagerIndexAction')
-    ->assert('type', '.+')
-    ->bind('admin_questionmanager');
-
-$app->match('/admin/questionmanager/questions', 'question_manager.controller:questionsAction', 'GET|POST')
-    ->assert('type', '.+')
-    ->bind('admin_questions');
-
+/*
 $app->match('/admin/questionmanager/questions/{id}/edit', 'question_manager.controller:editQuestionAction', 'GET|POST')
     ->assert('type', '.+')
     ->bind('admin_questions_edit');
@@ -644,16 +524,17 @@ $app->match('/admin/questionmanager/categories/new', 'question_manager.controlle
 
 $app->match('/admin/questionmanager/categories/{id}/delete', 'question_manager.controller:deleteCategoryAction', 'POST')
     ->bind('admin_category_delete');
+*/
 
 /** Exercises */
 $app->match('courses/{cidReq}/{id_session}/exercise/question-pool', 'exercise_manager.controller:questionPoolAction', 'POST')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userPermissionsInsideACourse)
     ->bind('exercise_question_pool_global');
 
 $app->match('courses/{cidReq}/{id_session}/exercise/{exerciseId}/question-pool', 'exercise_manager.controller:questionPoolAction', 'GET|POST')
     ->assert('exerciseId', '\d+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userCourseAdmin)
     ->before($userPermissionsInsideACourse)
     ->bind('exercise_question_pool');
@@ -661,7 +542,7 @@ $app->match('courses/{cidReq}/{id_session}/exercise/{exerciseId}/question-pool',
 $app->match('courses/{cidReq}/{id_session}/exercise/{exerciseId}/copy-question/{questionId}', 'exercise_manager.controller:copyQuestionAction', 'GET|POST')
     ->assert('questionId', '\d+')
     ->assert('exerciseId', '\d+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userCourseAdmin)
     ->before($userPermissionsInsideACourse)
     ->bind('exercise_copy_question');
@@ -669,7 +550,7 @@ $app->match('courses/{cidReq}/{id_session}/exercise/{exerciseId}/copy-question/{
 $app->match('courses/{cidReq}/{id_session}/exercise/{exerciseId}/reuse-question/{questionId}', 'exercise_manager.controller:reuseQuestionAction', 'GET|POST')
     ->assert('questionId', '\d+')
     ->assert('exerciseId', '\d+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userCourseAdmin)
     ->before($userPermissionsInsideACourse)
     ->bind('exercise_reuse_question');
@@ -679,7 +560,7 @@ $app->match('/courses/{cidReq}/{id_session}/exercise/question/{id}', 'exercise_m
     ->assert('id_session', '\d+')
     ->assert('id', '\d+')
     ->assert('type', '.+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userPermissionsInsideACourse)
     ->before($userCourseAdmin)
     ->bind('question_show');
@@ -689,7 +570,7 @@ $app->match('/courses/{cidReq}/{id_session}/exercise/{exerciseId}/question/{id}'
     ->assert('exerciseId', '\d+')
     ->assert('id', '\d+')
     ->assert('type', '.+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userPermissionsInsideACourse)
     ->before($userCourseAdmin)
     ->bind('exercise_question_show');
@@ -698,48 +579,50 @@ $app->match('/courses/{cidReq}/{id_session}/exercise/{exerciseId}/dashboard', 'e
     ->assert('id_session', '\d+')
     ->assert('exerciseId', '\d+')
     ->assert('type', '.+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userPermissionsInsideACourse)
     ->before($userCourseAdmin)
     ->bind('exercise_dashboard');
 
 $app->match('/courses/{cidReq}/{id_session}/exercise/question/{id}/edit', 'exercise_manager.controller:editQuestionAction', 'GET|POST')
     ->assert('type', '.+')
-    ->before($settingCourseConditions)
+    //->before($settingCourseConditions)
     ->before($userPermissionsInsideACourse)
     ->before($userCourseAdmin)
     ->bind('exercise_question_edit');
 
-$app->match('/admin/administrator/', 'admin.controller:indexAction', 'GET')
+/*$app->match('/ajax', 'model_ajax.controller:indexAction', 'GET')
     ->assert('type', '.+')
-    ->bind('admin_administrator');
-
-$app->match('/ajax', 'model_ajax.controller:indexAction', 'GET')
-    ->assert('type', '.+')
-    ->bind('model_ajax');
+    ->bind('model_ajax');*/
 
 if ($alreadyInstalled) {
     // Mount controllers.
     $controllers = array(
-        '/admin/' => 'admin.controller',
-        '/admin/administrator/upgrade' => 'upgrade.controller',
-        '/admin/administrator/roles' => 'role.controller',
-        '/admin/administrator/question_scores' => 'question_score.controller',
-        '/admin/administrator/question_score_names' => 'question_score_name.controller',
-        '/editor/' => 'editor.controller',
-        '/user/' => 'profile.controller',
-        '/app/session_path' => 'session_path.controller',
-        '/app/session_path/tree' => 'session_tree.controller',
-        '/courses/{course}/curriculum/category' => 'curriculum_category.controller',
-        '/courses/{course}/curriculum/item' => 'curriculum_item.controller',
-        '/courses/{course}/curriculum/user' => 'curriculum_user.controller',
-        '/courses/{course}/curriculum' => 'curriculum.controller',
-        '/courses/{course}/course_home' => 'course_home.controller',
-        '/courses/{course}/introduction' => 'introduction.controller',
+        //'/ajax' => 'model_ajax.controller',
+        //'/admin/' => 'admin.controller',
+        //'/admin/administrator/upgrade' => 'upgrade.controller',
+        //'/admin/administrator/branch' => 'branch.controller',
+        //'/admin/administrator/roles' => 'role.controller',
+        //'/admin/administrator/question_scores' => 'question_score.controller',
+        //'/admin/administrator/question_score_names' => 'question_score_name.controller',
+//        '/editor/' => 'editor.controller',
+        //'/user/' => 'profile.controller',
+        //'/app/session_path' => 'session_path.controller',
+        //'/app/session_path/tree' => 'session_tree.controller',
+        //'/courses/{course}/curriculum/category' => 'curriculum_category.controller',
+        //'/courses/{course}/curriculum/item' => 'curriculum_item.controller',
+        //'/courses/{course}/curriculum/user' => 'curriculum_user.controller',
+        //'/courses/{course}/curriculum' => 'curriculum.controller',
+        //'/courses/{course}/course_home' => 'course_home.controller',
+        //'/courses/{course}/introduction' => 'introduction.controller',
     );
-
-    foreach ($controllers as $route => $controller) {
-        $app->mount($route, new ReflectionControllerProvider($controller));
+    foreach ($app['controller_array'] as $route => $controllerInfo) {
+        if (isset($controllerInfo[1]) && $controllerInfo[1]) {
+            $app->mount(
+                $controllerInfo[1],
+                new ReflectionControllerProvider($route)
+            );
+        }
     }
 }
 

+ 125 - 160
src/ChamiloLMS/services.php

@@ -2,11 +2,10 @@
 /* For licensing terms, see /license.txt */
 
 /**
- * This file includes all the services that are loaded via the ServiceProviderInterface
- *
+ * This file includes all the services that are loaded via
+ * the ServiceProviderInterface
  * @package chamilo.services
  */
-
 use Doctrine\Common\Persistence\AbstractManagerRegistry;
 use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
 use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
@@ -35,7 +34,7 @@ use ChamiloLMS\Framework\PageController;
 use ChamiloLMS\Framework\Template;
 
 // Flint
-$app->register(new Flint\Provider\ConfigServiceProvider());
+$app->register(new Flint\Provider\TackerServiceProvider());
 $app['root_dir'] = $app['path.base'];
 
 $app->register(new Flint\Provider\RoutingServiceProvider(), array(
@@ -433,6 +432,7 @@ if (isset($app->getConfiguration()->main_database)) {
 $app['view_path'] = $app['path.base'].'src/ChamiloLMS/Resources/views/';
 
 // Setting Twig as a service provider.
+
 $app->register(
     new Silex\Provider\TwigServiceProvider(),
     array(
@@ -471,9 +471,8 @@ $app['twig'] = $app->share($app->extend('twig', function (\Twig_Environment $twi
 }));
 
 // Developer tools.
-
 if (is_writable($app['path.temp'])) {
-    if ($app['show_profiler']) {
+    if ($app->getConfiguration()->show_profiler) {
         // Adding Symfony2 web profiler (memory, time, logs, etc)
         $app->register(
             $p = new Silex\Provider\WebProfilerServiceProvider(),
@@ -484,7 +483,7 @@ if (is_writable($app['path.temp'])) {
         $app->mount('/_profiler', $p);
 
         // Better PHP errors
-        $app->register(new Whoops\Provider\Silex\WhoopsServiceProvider);
+        //$app->register(new Whoops\Provider\Silex\WhoopsServiceProvider);
 
         /*$app['xhprof.location'] = '/var/www/xhprof';
         $app['xhprof.host'] = 'http://localhost/xhprof/xhprof_html/index.php';
@@ -759,166 +758,132 @@ class ChamiloServiceProvider implements ServiceProviderInterface
 $app->register(new ChamiloServiceProvider(), array());
 
 // Controller as services definitions.
-$app['pages.controller'] = $app->share(
+/*$app['pages.controller'] = $app->share(
     function () use ($app) {
         return new PagesController($app['pages.repository']);
     }
-);
-
-//@todo improve loading of controllers.
-
-$app['index.controller'] = $app->share(
-    function () use ($app) {
-        $controller = new ChamiloLMS\Controller\IndexController($app);
-        return $controller;
-    }
-);
-
-$app['legacy.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\LegacyController($app);
-    }
-);
-
-$app['userPortal.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\UserPortalController($app);
-    }
-);
-
-$app['learnpath.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\LearnpathController();
-    }
-);
-
-$app['certificate.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\CertificateController();
-    }
-);
-
-$app['profile.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\User\ProfileController($app);
-    }
-);
-
-$app['user.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\User\UserController($app);
-    }
-);
-
-$app['news.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\NewsController();
-    }
-);
-
-$app['editor.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\EditorController($app);
-    }
-);
-
-$app['question_manager.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Admin\QuestionManager\QuestionManagerController();
-    }
-);
-
-$app['exercise_manager.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\ExerciseController($app);
-    }
-);
-
-$app['admin.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Admin\AdminController($app);
-    }
-);
-
-$app['role.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Admin\Administrator\RoleController($app);
-    }
-);
-
-$app['question_score.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Admin\Administrator\QuestionScoreController($app);
-    }
-);
-
-$app['question_score_name.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Admin\Administrator\QuestionScoreNameController($app);
-    }
-);
-
-$app['model_ajax.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\ModelAjaxController();
-    }
-);
-
-// Curriculum tool
-
-$app['curriculum.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Tool\Curriculum\CurriculumController($app);
-    }
-);
-
-$app['curriculum_category.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Tool\Curriculum\CurriculumCategoryController($app);
-    }
-);
-
-$app['curriculum_item.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Tool\Curriculum\CurriculumItemController($app);
-    }
-);
-
-$app['curriculum_user.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Tool\Curriculum\CurriculumUserController($app);
-    }
-);
-
-$app['session_path.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\App\SessionPath\SessionPathController($app);
-    }
-);
-
-$app['session_tree.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\App\SessionPath\SessionTreeController($app);
-    }
-);
+);*/
 
-$app['upgrade.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Admin\Administrator\UpgradeController($app);
-    }
+$controllers = array(
+    'index.controller' => array(
+        'IndexController',
+        '/'
+    ),
+    'legacy.controller' => array(
+        'LegacyController',
+        false
+    ),
+    // Admin group
+    'admin.controller' => array(
+        'Admin\AdminController',
+        '/admin/'
+    ),
+    'branch.controller' => array(
+        'Admin\Administrator\BranchController',
+        '/admin/administrator/branch'
+    ),
+    'jury.controller' => array(
+        'Admin\Administrator\JuryController',
+        '/admin/administrator/jury'
+    ),
+    'question_manager.controller' => array(
+        'Admin\QuestionManager\QuestionManagerController',
+        '/admin/questionmanager'
+    ),
+    'question_score.controller' => array(
+        'Admin\Administrator\QuestionScoreController',
+        '/admin/administrator/question_scores'
+    ),
+    'question_score_name.controller' => array(
+        'Admin\Administrator\QuestionScoreNameController',
+        '/admin/administrator/question_score_names'
+    ),
+    'role.controller' => array(
+        'Admin\Administrator\RoleController',
+        '/admin/administrator/roles'
+    ),
+    'upgrade.controller' => array(
+        'Admin\Administrator\UpgradeController',
+        '/admin/administrator/upgrade'
+    ),
+    // App group
+    'session_tree.controller' => array(
+        'App\SessionPath\SessionTreeController',
+        'app/session_path/tree'
+    ),
+    'session_path.controller' => array(
+        'App\SessionPath\SessionPathController',
+        'app/session_path'
+    ),
+    'model_ajax.controller' => array(
+        'App\ModelAjax\ModelAjaxController',
+        '/ajax'
+    ),
+    'editor.controller' => array(
+        'App\Editor\EditorController',
+        '/editor/'
+    ),
+    'news.controller' => array(
+        'App\News\NewsController',
+        '/app/news/'
+    ),
+    'certificate.controller' => array(
+        'App\Certificate\CertificateController',
+        '/app/certificates/'
+    ),
+    // Tools (Course Tools)
+    'course_home.controller' => array(
+        'Tool\CourseHome\CourseHomeController',
+        'courses/{courseCode}/'
+    ),
+    'introduction.controller' => array(
+        'Tool\Introduction\IntroductionController',
+        'courses/{courseCode}/introduction'
+    ),
+    'learnpath.controller' => array(
+        'Tool\LearningPath\LearningPathController',
+        'courses/{courseCode}/learning_path'
+    ),
+    'exercise_manager.controller' => array(
+        'Tool\Exercise\ExerciseController',
+        '/courses/{courseCode}/exercise2'
+    ),
+    'curriculum.controller' => array(
+        'Tool\Curriculum\CurriculumController',
+        '/courses/{courseCode}/curriculum'
+    ),
+    'curriculum_category.controller' => array(
+        'Tool\Curriculum\CurriculumCategoryController',
+        '/courses/{courseCode}/curriculum/category'
+    ),
+    'curriculum_item.controller' => array(
+        'Tool\Curriculum\CurriculumItemController',
+        '/courses/{courseCode}/curriculum/item'
+    ),
+    'curriculum_user.controller' => array(
+        'Tool\Curriculum\CurriculumUserController',
+        '/courses/{courseCode}/curriculum/user'
+    ),
+    // Users (Social)
+    'profile.controller' => array(
+        'User\ProfileController',
+        '/user/'
+    ),
+    'user.controller' => array(
+        'User\UserController',
+    )
 );
 
-$app['course_home.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Tool\CourseHome\CourseHomeController($app);
-    }
-);
+$app['controller_array'] = $controllers;
 
-$app['introduction.controller'] = $app->share(
-    function () use ($app) {
-        return new ChamiloLMS\Controller\Tool\Introduction\IntroductionController($app);
-    }
-);
+foreach ($controllers as $name => $controllerInfo) {
+    $class = 'ChamiloLMS\Controller\\' . $controllerInfo[0];
+    $app[$name] = $app->share(
+        function () use ($app, $class) {
+            return new $class($app);
+        }
+    );
+}
 
 /*if (isset($app['configuration']['unoconv.binaries'])) {
     $app->register(new Unoconv\UnoconvServiceProvider(), array(