Преглед изворни кода

Adding Installer bundle, fixing index page

Julio Montoya пре 10 година
родитељ
комит
4dc4cbe28a
43 измењених фајлова са 1654 додато и 412 уклоњено
  1. 3 1
      app/config/sonata/sonata_page.yml
  2. 4 4
      composer.json
  3. 12 0
      main/inc/lib/chamilo_session.class.php
  4. 2 0
      main/inc/lib/internationalization.lib.php
  5. 62 1
      src/ChamiloLMS/CoreBundle/Admin/CourseAdmin.php
  6. 14 0
      src/ChamiloLMS/CoreBundle/ChamiloLMSCoreBundle.php
  7. 13 2
      src/ChamiloLMS/CoreBundle/Controller/BaseController.php
  8. 4 157
      src/ChamiloLMS/CoreBundle/Controller/IndexController.php
  9. 2 3
      src/ChamiloLMS/CoreBundle/Controller/LegacyController.php
  10. 70 74
      src/ChamiloLMS/CoreBundle/DataFixtures/ORM/LoadPageData.php
  11. 0 3
      src/ChamiloLMS/CoreBundle/DataFixtures/ORM/LoadPortalData.php
  12. 46 7
      src/ChamiloLMS/CoreBundle/Entity/Course.php
  13. 41 0
      src/ChamiloLMS/CoreBundle/Entity/Listener/CourseListener.php
  14. 194 0
      src/ChamiloLMS/CoreBundle/Entity/TrackAttemptJury.php
  15. 1 1
      src/ChamiloLMS/CoreBundle/Entity/UsergroupRelUser.php
  16. 14 8
      src/ChamiloLMS/CoreBundle/EventListener/MessageListener.php
  17. 10 4
      src/ChamiloLMS/CoreBundle/EventListener/ShowUserListener.php
  18. 2 2
      src/ChamiloLMS/CoreBundle/Menu/MainMenuBuilder.php
  19. 7 41
      src/ChamiloLMS/CoreBundle/Menu/SimpleMenuBuilder.php
  20. 1 0
      src/ChamiloLMS/CoreBundle/Resources/config/admin.yml
  21. 0 5
      src/ChamiloLMS/CoreBundle/Resources/config/routing.yml
  22. 22 0
      src/ChamiloLMS/CoreBundle/Resources/config/services.yml
  23. 544 0
      src/ChamiloLMS/CoreBundle/Resources/views/Calendar/month.html.twig
  24. 2 0
      src/ChamiloLMS/CoreBundle/Resources/views/Index/index.html.twig
  25. 0 1
      src/ChamiloLMS/CoreBundle/Resources/views/Index/userportal.html.twig
  26. 8 0
      src/ChamiloLMS/CourseBundle/ChamiloLMSCourseBundle.php
  27. 89 11
      src/ChamiloLMS/CourseBundle/Controller/Home/HomeController.php
  28. 33 0
      src/ChamiloLMS/CourseBundle/DependencyInjection/Compiler/ToolCompilerClass.php
  29. 4 1
      src/ChamiloLMS/CourseBundle/Entity/CTool.php
  30. 0 0
      src/ChamiloLMS/CourseBundle/Resources/config/routing.yml
  31. 19 0
      src/ChamiloLMS/CourseBundle/Resources/config/services.yml
  32. 0 0
      src/ChamiloLMS/CourseBundle/Resources/views/Home/add.tpl
  33. 0 0
      src/ChamiloLMS/CourseBundle/Resources/views/Home/edit.tpl
  34. 2 0
      src/ChamiloLMS/CourseBundle/Resources/views/Home/index.html.twig
  35. 0 0
      src/ChamiloLMS/CourseBundle/Resources/views/Home/list.tpl
  36. 35 0
      src/ChamiloLMS/CourseBundle/Tool/BaseTool.php
  37. 36 0
      src/ChamiloLMS/CourseBundle/Tool/Calendar.php
  38. 37 0
      src/ChamiloLMS/CourseBundle/Tool/Document.php
  39. 36 0
      src/ChamiloLMS/CourseBundle/Tool/ToolInterface.php
  40. 36 0
      src/ChamiloLMS/CourseBundle/ToolChain.php
  41. 46 0
      src/ChamiloLMS/InstallerBundle/ChamiloLMSInstallerBundle.php
  42. 186 0
      src/ChamiloLMS/InstallerBundle/Command/InstallCommand.php
  43. 17 86
      tests/doctrine_console/cli-config.php

+ 3 - 1
app/config/sonata/sonata_page.yml

@@ -22,6 +22,7 @@ sonata_page:
         - ^_(.*)            # ignore symfony routes
         - login
         - home
+        - homepage
         - (.*)fos_user_(.*)
 
     ignore_routes:
@@ -82,7 +83,8 @@ sonata_page:
                      F: footer
 
         2columns:
-            path: 'ApplicationSonataPageBundle::default_2columns_layout.html.twig'
+            #path: 'ApplicationSonataPageBundle::default_2columns_layout.html.twig'
+            path: 'ChamiloLMSCoreBundle::main_layout.html.twig'
             name: '2 columns layout'
             containers:
                  header:

+ 4 - 4
composer.json

@@ -48,22 +48,22 @@
         "twig/twig": "~1.12",
         "twig/extensions": "~1.0",
 
-        "symfony/symfony": "~2.4",
+        "symfony/symfony": "~2.5",
 
         "symfony/assetic-bundle": "~2.3",
         "symfony/swiftmailer-bundle": "~2.3",
         "symfony/monolog-bundle": "~2.3",
 
         "sensio/distribution-bundle": "~2.3",
-        "sensio/framework-extra-bundle": "~2.3",
+        "sensio/framework-extra-bundle": "~3.0.0",
         "sensio/generator-bundle": "~2.3",
 
         "jms/security-extra-bundle": "~1.5",
         "jms/di-extra-bundle": "~1.4",
         "jms/serializer-bundle": "~0.11",
 
-        "doctrine/orm": "~2.4",
-        "doctrine/doctrine-bundle": "~1.2",
+        "doctrine/orm": "2.4.2",
+        "doctrine/doctrine-bundle": "~1.3@dev",
         "doctrine/doctrine-migrations-bundle": "dev-master",
         "doctrine/migrations": "dev-master",
         "doctrine/doctrine-fixtures-bundle": "~2.2",

+ 12 - 0
main/inc/lib/chamilo_session.class.php

@@ -19,6 +19,7 @@ class ChamiloSession
     public static $configDir;
     public static $assets;
     public static $htmlEditor;
+    public static $twig;
 
     /**
      * @return string
@@ -28,6 +29,9 @@ class ChamiloSession
         return self::$configDir;
     }
 
+    /**
+     * @return string
+     */
     public static function getLogDir()
     {
         return self::$logDir;
@@ -65,6 +69,14 @@ class ChamiloSession
         return self::$courseDir;
     }
 
+    /**
+     * @return Twig_Environment
+     */
+    public static function getTwig()
+    {
+        return self::$twig;
+    }
+
     /**
      * @return ChamiloLMS\CoreBundle\Component\Editor\Editor
      */

+ 2 - 0
main/inc/lib/internationalization.lib.php

@@ -123,6 +123,8 @@ function api_purify_language_id($language)
  */
 function api_get_language_isocode($language = null, $default_code = 'en')
 {
+    return Session::getTranslator()->getLocale();
+
     static $iso_code = array();
     if (empty($language)) {
         $language = api_get_interface_language(false, true);

+ 62 - 1
src/ChamiloLMS/CoreBundle/Admin/CourseAdmin.php

@@ -2,11 +2,14 @@
 
 namespace ChamiloLMS\CoreBundle\Admin;
 
+use ChamiloLMS\CoreBundle\Entity\Listener\CourseListener;
+use ChamiloLMS\CourseBundle\Entity\CTool;
 use Sonata\AdminBundle\Admin\Admin;
 use Sonata\AdminBundle\Form\FormMapper;
 use Sonata\AdminBundle\Datagrid\DatagridMapper;
 use Sonata\AdminBundle\Datagrid\ListMapper;
 use Sonata\AdminBundle\Show\ShowMapper;
+use ChamiloLMS\CourseBundle\ToolChain;
 
 use Knp\Menu\ItemInterface as MenuItemInterface;
 
@@ -80,8 +83,8 @@ class CourseAdmin extends Admin
     {
         $listMapper
             ->addIdentifier('id')
-            ->addIdentifier('code')
             ->addIdentifier('title')
+            ->addIdentifier('code')
         ;
     }
 
@@ -94,5 +97,63 @@ class CourseAdmin extends Admin
     {
         $course->setUsers($course->getUsers());
         $course->setUrls($course->getUrls());
+        $this->updateTools($course);
+    }
+
+    /**
+     * @param Course $course
+     * @return mixed|void
+     */
+    public function prePersist($course)
+    {
+        $this->updateTools($course);
+    }
+
+    /***
+     * @param Course $course
+     */
+    public function updateTools($course)
+    {
+        $toolChain = $this->getToolChain();
+        $tools = $toolChain->getTools();
+
+        $currentTools = $course->getTools();
+        $addedTools = array();
+        if (!empty($currentTools)) {
+            foreach ($currentTools as $tool) {
+                $addedTools[] = $tool->getName();
+            }
+        }
+
+        foreach ($tools as $tool) {
+            $toolName = $tool->getName();
+            if (!in_array($toolName, $addedTools)) {
+
+                $toolEntity = new CTool();
+                $toolEntity->setCId($course->getId());
+                $toolEntity->setName($tool->getName());
+                $toolEntity->setLink($tool->getLink());
+                $toolEntity->setTarget($tool->getTarget());
+                $toolEntity->setCategory($tool->getCategory());
+
+                $course->addTools($toolEntity);
+            }
+        }
+    }
+
+    /**
+     * @param ToolChain $chainTool
+     */
+    public function setToolChain(ToolChain $chainTool)
+    {
+        $this->toolChain = $chainTool;
+    }
+
+    /**
+     * @return ToolChain
+     */
+    public function getToolChain()
+    {
+        return $this->toolChain;
     }
 }

+ 14 - 0
src/ChamiloLMS/CoreBundle/ChamiloLMSCoreBundle.php

@@ -2,8 +2,22 @@
 
 namespace ChamiloLMS\CoreBundle;
 
+use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
+use ChamiloLMS\CoreBundle\DependencyInjection\Compiler\DoctrineEntityListenerPass;
 use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
 
 class ChamiloLMSCoreBundle extends Bundle
 {
+    public function boot()
+    {
+        // Add legacy calls.
+    }
+
+    public function build(ContainerBuilder $container)
+    {
+        parent::build($container);
+        //$container->addCompilerPass(new EntityListenerPass());
+        //$container->addCompilerPass(new DoctrineEntityListenerPass());
+    }
 }

+ 13 - 2
src/ChamiloLMS/CoreBundle/Controller/BaseController.php

@@ -34,7 +34,7 @@ abstract class BaseController extends Controller
     }
 
     /**
-     * @return Symfony\Component\HttpFoundation\Session\SessionInterface
+     * @return \Symfony\Component\HttpFoundation\Session\SessionInterface
      */
     public function getSessionHandler()
     {
@@ -57,6 +57,18 @@ abstract class BaseController extends Controller
         return new NotFoundHttpException();
     }
 
+    /**
+     * @param string $message
+     * @param string $class
+     */
+    public function addMessage($message, $class)
+    {
+        $this->get('session')->getFlashBag()->add(
+            $class,
+            $message
+        );
+    }
+
     /**
      * Converts string 'ChamiloLMS\CoreBundle\Controller\Admin\QuestionManager' into
      * 'admin/question_manager'
@@ -232,7 +244,6 @@ abstract class BaseController extends Controller
      */
     public function getCourse()
     {
-        var_dump($this->getSessionHandler()->get('course'));
         return $this->getSessionHandler()->get('course');
     }
 

+ 4 - 157
src/ChamiloLMS/CoreBundle/Controller/IndexController.php

@@ -11,12 +11,10 @@ use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\Finder\Finder;
-
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
-//use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
-use JMS\SecurityExtraBundle\Annotation\Secure;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
 
 /**
  * Class IndexController
@@ -25,11 +23,6 @@ use JMS\SecurityExtraBundle\Annotation\Secure;
  */
 class IndexController extends BaseController
 {
-    /**
-     * @Route("/home", name="homepage")
-     * @Method({"GET"})
-     * @return Response
-     */
     public function indexAction()
     {
         /** @var \PageController $pageController */
@@ -77,7 +70,7 @@ class IndexController extends BaseController
         return $this->render(
             'ChamiloLMSCoreBundle:Index:index.html.twig',
             array(
-                'content' => null,
+                'content' => 'hello',
                 'hot_courses' => $hotCourses,
                 'announcements_block' => $announcementsBlock,
                 //'home_page_block' => $pageController->returnHomePage()
@@ -85,98 +78,6 @@ class IndexController extends BaseController
         );
     }
 
-    /**
-     * @param Application $app
-     * @return Response
-     */
-    public function loginAction(Application $app)
-    {
-        $request = $this->getRequest();
-        $app['template']->assign('error', $app['security.last_error']($request));
-        $extra = array();
-        if (api_get_setting('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($extra, 'string');
-        $response = $app['template']->render_template('auth/login.tpl');
-        return new Response($response, 200, array('Cache-Control' => 's-maxage=3600, public'));
-    }
-
-    /**
-     * @param
-     *
-     * @return string
-     */
-    public function displayLoginForm()
-    {
-        /* {{ form_widget(form) }}
-          $form = $app['form.factory']->createBuilder('form')
-          ->add('name')
-          ->add('email')
-          ->add('gender', 'choice', array(
-          'choices' => array(1 => 'male', 2 => 'female'),
-          'expanded' => true,
-          ))
-          ->getForm();
-          return $app['template']->assign('form', $form->createView());
-         */
-        $form = new \FormValidator(
-            'formLogin',
-            'POST',
-            $this->get('url_generator')->generate('secured_login_check'),
-            null,
-            array('class'=> 'form-signin-block')
-        );
-
-        $form->addElement(
-            'text',
-            'username',
-            null,
-            array(
-                'class' => 'input-medium autocapitalize_off virtualkey',
-                'placeholder' => get_lang('UserName'),
-                'autofocus' => 'autofocus',
-                'icon' => 'fa fa-user fa-fw'
-            )
-        );
-
-        $form->addElement(
-            'password',
-            'password',
-            null,
-            array(
-                'placeholder' => get_lang('Pass'),
-                'class' => 'input-medium virtualkey',
-                '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();
-
-        /** Verify if settings is active to set keyboard. Included extra class in form input elements */
-
-        if (api_get_setting('use_virtual_keyboard') == 'true') {
-            $html .= "<script>
-                $(function(){
-                    $('.virtualkey').keyboard({
-                        layout:'custom',
-                        customLayout: {
-                        'default': [
-                            '1 2 3 4 5 6 7 8 9 0 {bksp}',
-                            'q w e r t y u i o p',
-                            'a s d f g h j k l',
-                            'z x c v b n m',
-                            '{cancel} {accept}'
-                        ]
-                        }
-                    });
-                });
-            </script>";
-        }
-        return $html;
-    }
 
     /**
      * @todo move all this getDocument* actions into another controller
@@ -311,63 +212,10 @@ class IndexController extends BaseController
         }
     }
 
-    /**
-     * Reacts on a failed login.
-     * Displays an explanation with a link to the registration form.
-     *
-     * @todo use twig template to prompt errors + move this into a helper
-     */
-    private function handleLoginFailed($error)
-    {
-        $message = get_lang('InvalidId');
-
-        if (!isset($error)) {
-            if (api_is_self_registration_allowed()) {
-                $message = get_lang('InvalidForSelfRegistration');
-            }
-        } else {
-            switch ($error) {
-                case '':
-                    if (api_is_self_registration_allowed()) {
-                        $message = get_lang('InvalidForSelfRegistration');
-                    }
-                    break;
-                case 'account_expired':
-                    $message = get_lang('AccountExpired');
-                    break;
-                case 'account_inactive':
-                    $message = get_lang('AccountInactive');
-                    break;
-                case 'user_password_incorrect':
-                    $message = get_lang('InvalidId');
-                    break;
-                case 'access_url_inactive':
-                    $message = get_lang('AccountURLInactive');
-                    break;
-                case 'unrecognize_sso_origin':
-                    //$message = get_lang('SSOError');
-                    break;
-            }
-        }
-        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());*/
-    }
-
     /**
      * @Route("/userportal", name="userportal")
      * @Method({"GET"})
-     * Security("has_role('ROLE_USER')")
-     * @Secure(roles="ROLE_STUDENT")
+     * @Security("has_role('ROLE_USER')")
      *
      * @param string $type courses|sessions|mycoursecategories
      * @param string $filter for the userportal courses page. Only works when setting 'history'
@@ -377,9 +225,7 @@ class IndexController extends BaseController
     public function userPortalAction($type = 'courses', $filter = 'current', $page = 1)
     {
         $user = $this->getUser();
-
         $pageController = new \ChamiloLMS\CoreBundle\Framework\PageController();
-
         $items = null;
 
         if (!empty($user)) {
@@ -449,6 +295,7 @@ class IndexController extends BaseController
      * Toggle the student view action
      *
      * @Route("/toggle_student_view")
+     * @Security("has_role('ROLE_TEACHER')")
      * @Method({"GET"})
      *
      * @return Response

+ 2 - 3
src/ChamiloLMS/CoreBundle/Controller/LegacyController.php

@@ -48,16 +48,15 @@ class LegacyController extends BaseController
         Session::$urlGenerator = $this->container->get('router');
         Session::$security = $this->container->get('security.context');
         Session::$translator = $this->container->get('translator');
-
         Session::$assets = $this->container->get('templating.helper.assets');
-
         Session::$rootDir = $this->container->get('kernel')->getRealRootDir();
         Session::$logDir = $this->container->get('kernel')->getLogDir();
         Session::$dataDir = $this->container->get('kernel')->getDataDir();
         Session::$tempDir = $this->container->get('kernel')->getCacheDir();
         Session::$courseDir = $this->container->get('kernel')->getDataDir();
-        Session::$configDir = $this->container->get('kernel')->getConfigDir();
+        //Session::$configDir = $this->container->get('kernel')->getConfigDir();
         Session::$htmlEditor = $this->container->get('html_editor');
+        Session::$twig = $this->container->get('twig');
 
         if (is_file($fileToLoad) &&
             \Security::check_abs_path($fileToLoad, $mainPath)

+ 70 - 74
src/ChamiloLMS/CoreBundle/DataFixtures/ORM/LoadPageData.php

@@ -76,7 +76,6 @@ class LoadPageData extends AbstractFixture implements ContainerAwareInterface, O
         $site->setEnabledTo(new \DateTime('+20 years'));
         $site->setRelativePath("");
         $site->setIsDefault(true);
-
         $this->getSiteManager()->save($site);
 
         return $site;
@@ -229,11 +228,11 @@ CONTENT
      */
     public function createHomePage(SiteInterface $site)
     {
-        return;
         $pageManager = $this->getPageManager();
         $blockManager = $this->getBlockManager();
         $blockInteractor = $this->getBlockInteractor();
 
+        /** @var \Sonata\PageBundle\Model\Page $homepage */
         $this->addReference('page-homepage', $homepage = $pageManager->create());
         $homepage->setSlug('/');
         $homepage->setUrl('/');
@@ -243,43 +242,28 @@ CONTENT
         $homepage->setDecorate(0);
         $homepage->setRequestMethod('GET|POST|HEAD|DELETE|PUT');
         $homepage->setTemplateCode('2columns');
-        $homepage->setRouteName('homepage');
+        $homepage->setRouteName(PageInterface::PAGE_ROUTE_CMS_NAME);
         $homepage->setSite($site);
-
         $pageManager->save($homepage);
 
-        // CREATE A HEADER BLOCK
+        // Header
         $homepage->addBlocks($contentTop = $blockInteractor->createNewContainer(array(
             'enabled' => true,
             'page' => $homepage,
             'code' => 'content_top',
         )));
-
         $contentTop->setName('The container top container');
-
         $blockManager->save($contentTop);
 
-        // add a block text
+        // Add a block text for the header
         $contentTop->addChildren($text = $blockManager->create());
         $text->setType('sonata.block.service.text');
-        $text->setSetting('content', <<<CONTENT
-<div class="col-md-3 welcome"><h2>Welcome</h2></div>
-<div class="col-md-9">
-    <p>
-        This page is a demo.
-    </p>
-
-    <p>
-        Pages.
-    </p>
-</div>
-CONTENT
-        );
+        $text->setSetting('content', 'Welcome to Chamilo (header)');
         $text->setPosition(1);
         $text->setEnabled(true);
         $text->setPage($homepage);
 
-
+        // Create content block
         $homepage->addBlocks($content = $blockInteractor->createNewContainer(array(
             'enabled' => true,
             'page' => $homepage,
@@ -288,7 +272,17 @@ CONTENT
         $content->setName('The content container');
         $blockManager->save($content);
 
-        /*
+        // Add a block text for the content
+        $contentTop->addChildren($text = $blockManager->create());
+        $text->setType('sonata.block.service.text');
+        $text->setSetting('content', 'Welcome to chamilo (content)');
+        $text->setPosition(1);
+        $text->setEnabled(true);
+        $text->setPage($homepage);
+
+        return;
+
+
         // Add media gallery block
         $content->addChildren($gallery = $blockManager->create());
         $gallery->setType('sonata.media.block.gallery');
@@ -299,58 +293,60 @@ CONTENT
         $gallery->setEnabled(true);
         $gallery->setPage($homepage);
 
-        // Add recent products block
-        $content->addChildren($newProductsBlock = $blockManager->create());
-        $newProductsBlock->setType('sonata.product.block.recent_products');
-        $newProductsBlock->setSetting('number', 4);
-        $newProductsBlock->setSetting('title', 'New products');
-        $newProductsBlock->setPosition(2);
-        $newProductsBlock->setEnabled(true);
-        $newProductsBlock->setPage($homepage);
-
-        // Add homepage bottom container
-        $homepage->addBlocks($bottom = $blockInteractor->createNewContainer(array(
-            'enabled' => true,
-            'page'    => $homepage,
-            'code'    => 'content_bottom',
-        ), function ($container) {
-            $container->setSetting('layout', '{{ CONTENT }}');
-        }));
-        $bottom->setName('The bottom content container');
+        /*
 
-        // Add homepage newsletter container
-        $bottom->addChildren($bottomNewsletter = $blockInteractor->createNewContainer(array(
-            'enabled' => true,
-            'page'    => $homepage,
-            'code'    => 'bottom_newsletter',
-        ), function ($container) {
-            $container->setSetting('layout', '<div class="block-newsletter col-sm-6 well">{{ CONTENT }}</div>');
-        }));
-        $bottomNewsletter->setName('The bottom newsetter container');
-        $bottomNewsletter->addChildren($newsletter = $blockManager->create());
-        $newsletter->setType('sonata.demo.block.newsletter');
-        $newsletter->setPosition(1);
-        $newsletter->setEnabled(true);
-        $newsletter->setPage($homepage);
-
-        // Add homepage embed tweet container
-        $bottom->addChildren($bottomEmbed = $blockInteractor->createNewContainer(array(
-            'enabled' => true,
-            'page'    => $homepage,
-            'code'    => 'bottom_embed',
-        ), function ($container) {
-            $container->setSetting('layout', '<div class="col-sm-6">{{ CONTENT }}</div>');
-        }));
-        $bottomEmbed->setName('The bottom embedded tweet container');
-        $bottomEmbed->addChildren($embedded = $blockManager->create());
-        $embedded->setType('sonata.seo.block.twitter.embed');
-        $embedded->setPosition(1);
-        $embedded->setEnabled(true);
-        $embedded->setSetting('tweet', "https://twitter.com/dunglas/statuses/438337742565826560");
-        $embedded->setSetting('lang', "en");
-        $embedded->setPage($homepage);
-
-        $pageManager->save($homepage);*/
+       // Add recent products block
+       $content->addChildren($newProductsBlock = $blockManager->create());
+       $newProductsBlock->setType('sonata.product.block.recent_products');
+       $newProductsBlock->setSetting('number', 4);
+       $newProductsBlock->setSetting('title', 'New products');
+       $newProductsBlock->setPosition(2);
+       $newProductsBlock->setEnabled(true);
+       $newProductsBlock->setPage($homepage);
+
+       // Add homepage bottom container
+       $homepage->addBlocks($bottom = $blockInteractor->createNewContainer(array(
+           'enabled' => true,
+           'page'    => $homepage,
+           'code'    => 'content_bottom',
+       ), function ($container) {
+           $container->setSetting('layout', '{{ CONTENT }}');
+       }));
+       $bottom->setName('The bottom content container');
+
+       // Add homepage newsletter container
+       $bottom->addChildren($bottomNewsletter = $blockInteractor->createNewContainer(array(
+           'enabled' => true,
+           'page'    => $homepage,
+           'code'    => 'bottom_newsletter',
+       ), function ($container) {
+           $container->setSetting('layout', '<div class="block-newsletter col-sm-6 well">{{ CONTENT }}</div>');
+       }));
+       $bottomNewsletter->setName('The bottom newsetter container');
+       $bottomNewsletter->addChildren($newsletter = $blockManager->create());
+       $newsletter->setType('sonata.demo.block.newsletter');
+       $newsletter->setPosition(1);
+       $newsletter->setEnabled(true);
+       $newsletter->setPage($homepage);
+
+       // Add homepage embed tweet container
+       $bottom->addChildren($bottomEmbed = $blockInteractor->createNewContainer(array(
+           'enabled' => true,
+           'page'    => $homepage,
+           'code'    => 'bottom_embed',
+       ), function ($container) {
+           $container->setSetting('layout', '<div class="col-sm-6">{{ CONTENT }}</div>');
+       }));
+       $bottomEmbed->setName('The bottom embedded tweet container');
+       $bottomEmbed->addChildren($embedded = $blockManager->create());
+       $embedded->setType('sonata.seo.block.twitter.embed');
+       $embedded->setPosition(1);
+       $embedded->setEnabled(true);
+       $embedded->setSetting('tweet', "https://twitter.com/dunglas/statuses/438337742565826560");
+       $embedded->setSetting('lang', "en");
+       $embedded->setPage($homepage);
+
+       $pageManager->save($homepage);*/
     }
 
     /**

+ 0 - 3
src/ChamiloLMS/CoreBundle/DataFixtures/ORM/LoadPortalData.php

@@ -258,9 +258,6 @@ class LoadPortalData extends AbstractFixture implements ContainerAwareInterface,
         $manager->persist($tool);
 
         $manager->flush();
-
-
-
     }
 
     /**

+ 46 - 7
src/ChamiloLMS/CoreBundle/Entity/Course.php

@@ -2,13 +2,14 @@
 
 namespace ChamiloLMS\CoreBundle\Entity;
 
+use ChamiloLMS\CourseBundle\Entity\CTool;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\ArrayCollection;
 use Gedmo\Mapping\Annotation as Gedmo;
 
 /**
  * Course
- *
+ * @ORM\HasLifecycleCallbacks
  * @ORM\Table(name="course")
  * @ORM\Entity(repositoryClass="ChamiloLMS\CoreBundle\Entity\Repository\CourseRepository")
  */
@@ -221,21 +222,30 @@ class Course
      **/
     private $items;
 
+    /**
+     * @ORM\OneToMany(targetEntity="ChamiloLMS\CourseBundle\Entity\CTool", mappedBy="course", cascade={"persist"})
+     **/
+    private $tools;
+
     /**
      * ORM\OneToMany(targetEntity="CurriculumCategory", mappedBy="course")
      **/
     //private $curriculumCategories;
 
-    public function __toString()
+    /**
+     *
+     */
+    public function __construct()
     {
-        return strval($this->getTitle());
     }
 
-    /*public function __construct()
+    /**
+     * @return string
+     */
+    public function __toString()
     {
-        $this->users = new ArrayCollection();
-        $this->items = new ArrayCollection();
-    }*/
+        return strval($this->getTitle());
+    }
 
     /**
      * @return mixed
@@ -253,6 +263,35 @@ class Course
         return $this->items;
     }
 
+    /**
+     * @return ArrayCollection
+     */
+    public function getTools()
+    {
+        return $this->tools;
+    }
+
+    /**
+     * @param $tools
+     */
+    public function setTools($tools)
+    {
+        $this->tools = new ArrayCollection();
+
+        foreach ($tools as $tool) {
+            $this->addTool($tool);
+        }
+    }
+
+    /**
+     * @param CTool $tool
+     */
+    public function addTools(CTool $tool)
+    {
+        $tool->setCourse($this);
+        $this->tools[] = $tool;
+    }
+
     /**
      * @return ArrayCollection
      */

+ 41 - 0
src/ChamiloLMS/CoreBundle/Entity/Listener/CourseListener.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace ChamiloLMS\CoreBundle\Entity\Listener;
+
+use Doctrine\ORM\Event\LifecycleEventArgs;
+use ChamiloLMS\CoreBundle\Entity\Course;
+
+/**
+ * Class CourseListener
+ * @package ChamiloLMS\CoreBundle\EventListener
+ */
+class CourseListener
+{
+    private $toolChain;
+
+    /**
+     * @param $toolChain
+     */
+    public function __construct($toolChain)
+    {
+        $this->toolChain = $toolChain;
+    }
+
+    /**
+     * new object : prePersist
+     * edited object: preUpdate
+     * @param LifecycleEventArgs $args
+     */
+    public function prePersist(Course $course, LifecycleEventArgs $args)
+    {
+
+        foreach ($this->toolChain as $tool) {
+            $tool->getName();
+        }
+        $course->setDescription( ' dq sdqs dqs dqs ');
+        $args->getEntityManager()->persist($course);
+        $args->getEntityManager()->flush();
+        var_dump($this->toolChain);
+
+    }
+}

+ 194 - 0
src/ChamiloLMS/CoreBundle/Entity/TrackAttemptJury.php

@@ -0,0 +1,194 @@
+<?php
+
+namespace ChamiloLMS\CoreBundle\Entity;
+
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * TrackAttemptJury
+ *
+ * @ORM\Table(name="track_attempt_jury")
+ * @ORM\Entity
+ */
+class TrackAttemptJury
+{
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
+     * @ORM\Id
+     * @ORM\GeneratedValue(strategy="AUTO")
+     */
+    private $id;
+
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="exe_id", type="integer", precision=0, scale=0, nullable=true, unique=false)
+     */
+    private $exeId;
+
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="question_id", type="integer", precision=0, scale=0, nullable=true, unique=false)
+     */
+    private $questionId;
+
+    /**
+     * @var float
+     *
+     * @ORM\Column(name="score", type="float", precision=0, scale=0, nullable=true, unique=false)
+     */
+    private $score;
+
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="jury_member_id", type="integer", precision=0, scale=0, nullable=true, unique=false)
+     */
+    private $juryMemberId;
+
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="question_score_name_id", type="integer", precision=0, scale=0, nullable=true, unique=false)
+     */
+    private $questionScoreNameId;
+
+    /**
+     * @ORM\ManyToOne(targetEntity="TrackEExercices", inversedBy="juryAttempts")
+     * @ORM\JoinColumn(name="exe_id", referencedColumnName="exe_id")
+     */
+    private $attempt;
+
+    public function getAttempt()
+    {
+        return $this->attempt;
+    }
+
+    /**
+     * Get id
+     *
+     * @return integer
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Set exeId
+     *
+     * @param integer $exeId
+     * @return TrackAttemptJury
+     */
+    public function setExeId($exeId)
+    {
+        $this->exeId = $exeId;
+
+        return $this;
+    }
+
+    /**
+     * Get exeId
+     *
+     * @return integer
+     */
+    public function getExeId()
+    {
+        return $this->exeId;
+    }
+
+    /**
+     * Set questionId
+     *
+     * @param integer $questionId
+     * @return TrackAttemptJury
+     */
+    public function setQuestionId($questionId)
+    {
+        $this->questionId = $questionId;
+
+        return $this;
+    }
+
+    /**
+     * Get questionId
+     *
+     * @return integer
+     */
+    public function getQuestionId()
+    {
+        return $this->questionId;
+    }
+
+    /**
+     * Set score
+     *
+     * @param float $score
+     * @return TrackAttemptJury
+     */
+    public function setScore($score)
+    {
+        $this->score = $score;
+
+        return $this;
+    }
+
+    /**
+     * Get score
+     *
+     * @return float
+     */
+    public function getScore()
+    {
+        return $this->score;
+    }
+
+    /**
+     * Set juryMemberId
+     *
+     * @param integer $juryMemberId
+     * @return TrackAttemptJury
+     */
+    public function setJuryMemberId($juryMemberId)
+    {
+        $this->juryMemberId = $juryMemberId;
+
+        return $this;
+    }
+
+    /**
+     * Get juryMemberId
+     *
+     * @return integer
+     */
+    public function getJuryMemberId()
+    {
+        return $this->juryMemberId;
+    }
+
+    /**
+     * Set questionScoreNameId
+     *
+     * @param integer $questionScoreNameId
+     * @return TrackAttemptJury
+     */
+    public function setQuestionScoreNameId($questionScoreNameId)
+    {
+        $this->questionScoreNameId = $questionScoreNameId;
+
+        return $this;
+    }
+
+    /**
+     * Get questionScoreNameId
+     *
+     * @return integer
+     */
+    public function getQuestionScoreNameId()
+    {
+        return $this->questionScoreNameId;
+    }
+}

+ 1 - 1
src/ChamiloLMS/CoreBundle/Entity/UsergroupRelUser.php

@@ -25,7 +25,7 @@ class UsergroupRelUser
     /**
      * @var \User
      *
-     * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User")
+     * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="classes")
      * @ORM\JoinColumns({
      *   @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
      * })

+ 14 - 8
src/ChamiloLMS/CoreBundle/EventListener/MessageListener.php

@@ -24,21 +24,27 @@ class MessageListener
 
     protected function getMessages()
     {
+        return array();
+
         $threads = $this->container->get('fos_message.provider')->getInboxThreads();
         $security = $this->container->get('security.context');
         $token = $security->getToken();
-        $user = $token->getUser();
-        $messages = array();
 
-        /** @var \ChamiloLMS\CoreBundle\Entity\Thread $thread*/
-        foreach ($threads as $thread) {
-            if ($thread->isReadByParticipant($user)) {
-                foreach($thread->getMessages() as $message) {
-                    $messages[] = $message;
+        $user = $token->getUser();
+        if (!empty($user)) {
+            $messages = array();
+
+            /** @var \ChamiloLMS\CoreBundle\Entity\Thread $thread */
+            foreach ($threads as $thread) {
+                if ($thread->isReadByParticipant($user)) {
+                    foreach ($thread->getMessages() as $message) {
+                        $messages[] = $message;
+                    }
                 }
             }
+
+            return $messages;
         }
 
-        return $messages;
     }
 }

+ 10 - 4
src/ChamiloLMS/CoreBundle/EventListener/ShowUserListener.php

@@ -19,16 +19,22 @@ class ShowUserListener
     public function onShowUser(ShowUserEvent $event)
     {
         $user = $this->getUser();
-        $event->setUser($user);
+        if (!empty($user)) {
+            $event->setUser($user);
+        }
     }
 
     public function getUser()
     {
+        /** @var  $security */
         $security = $this->container->get('security.context');
         $token = $security->getToken();
 
-
-        // $user = $this->getUser();
-        return $token->getUser();
+        if ($token) {
+            $user = $token->getUser();
+            if ($user) {
+                return $user;
+            }
+        }
     }
 }

+ 2 - 2
src/ChamiloLMS/CoreBundle/Menu/MainMenuBuilder.php

@@ -22,8 +22,8 @@ class MainMenuBuilder extends ContainerAware
     /**
      * Constructor
      *
-     * @param MenuFactory                     $factory
-     * @param RouterInterface                 $router
+     * @param MenuFactory $factory
+     * @param RouterInterface $router
      */
     public function __construct(FactoryInterface $factory, RouterInterface $router)
     {

+ 7 - 41
src/ChamiloLMS/CoreBundle/Menu/SimpleMenuBuilder.php

@@ -4,7 +4,6 @@ namespace ChamiloLMS\CoreBundle\Menu;
 
 use Knp\Menu\FactoryInterface;
 use Symfony\Component\DependencyInjection\ContainerAware;
-use Avanzu\AdminThemeBundle\Model\MenuItemInterface as ThemeMenuItem;
 
 /**
  * Class Builder
@@ -27,50 +26,16 @@ class SimpleMenuBuilder extends ContainerAware
     {
         $isFooter = array_key_exists('is_footer', $options) ? $options['is_footer'] : false;
 
-        $shopCategories = $this->container->get('sonata.classification.manager.category')->findBy(array('enabled' => true, 'parent' => null));
-
         $menuOptions = array_merge($options, array(
             'childrenAttributes' => array('class' => 'nav nav-pills'),
         ));
 
         $menu = $factory->createItem('main', $menuOptions);
+        $child = $menu->addChild('News', array('route' => 'sonata_news_home', array("attributes" => array("id" => 'nav'))));
 
-        //$shopMenuParams = array('route' => 'sonata_catalog_index');
-        $shopMenuParams = array('route' => 'home');
-
-        if (count($shopCategories) > 0 && !$isFooter) {
-            $shopMenuParams = array_merge($shopMenuParams, array(
-                'attributes' => array('class' => 'dropdown'),
-                'childrenAttributes' => array('class' => 'dropdown-menu'),
-                'linkAttributes' => array('class' => 'dropdown-toggle', 'data-toggle' => 'dropdown', 'data-target' => '#'),
-                'label' => 'Products <b class="caret caret-menu"></b>',
-                'extras' => array(
-                    'safe_label' => true,
-                )
-            ));
-        }
-
-        if ($isFooter) {
-            $shopMenuParams = array_merge($shopMenuParams, array(
-                'attributes' => array('class' => 'span2'),
-                "childrenAttributes" => array('class' => 'nav')
-            ));
-        }
 
-        $shop = $menu->addChild('Shops', $shopMenuParams);
-
-        $menu->addChild('News', array('route' => 'sonata_news_home'));
-
-        foreach ($shopCategories as $category) {
-            $shop->addChild($category->getName(), array(
-                'route' => 'sonata_catalog_category',
-                'routeParameters' => array(
-                    'category_id'   => $category->getId(),
-                    'category_slug' => $category->getSlug()),
-                )
-            );
-        }
 
+        /*
         $dropdownExtrasOptions = $isFooter ? array(
             'uri' => "#",
             'attributes' => array('class' => 'span2'),
@@ -91,15 +56,16 @@ class SimpleMenuBuilder extends ContainerAware
         $extras->addChild('Api', array('route' => 'page_slug', 'routeParameters' => array('path' => '/api-landing')));
         $extras->addChild('Gallery', array('route' => 'sonata_media_gallery_index'));
         $extras->addChild('Media & SEO', array('route' => 'home'));
-        //$extras->addChild('Media & SEO', array('route' => 'sonata_demo_media'));
 
         $menu->addChild($extras);
+        */
 
         $menu->addChild('Admin', array(
             'route' => 'page_slug',
             'routeParameters' => array(
                 'path' => '/user'
-            )
+            ),
+            'id' => 'admin'
         ));
 
         if ($isFooter) {
@@ -107,10 +73,10 @@ class SimpleMenuBuilder extends ContainerAware
                 'route' => 'page_slug',
                 'routeParameters' => array(
                     'path' => '/legal-notes',
-                )
+                ),
+                'id' => 'legal'
             ));
         }
-
         return $menu;
     }
 

+ 1 - 0
src/ChamiloLMS/CoreBundle/Resources/config/admin.yml

@@ -9,6 +9,7 @@ services:
             - ~
         calls:
             - [ setTranslationDomain, [ChamiloLMSCoreBundle]]
+            - [ setToolChain, [@chamilolms.tool_chain]]
 
     sonata.admin.session:
         class: ChamiloLMS\CoreBundle\Admin\SessionAdmin

+ 0 - 5
src/ChamiloLMS/CoreBundle/Resources/config/routing.yml

@@ -3,11 +3,6 @@ index:
     type:     annotation
     prefix:   /
 
-front:
-    resource: "@ChamiloLMSCoreBundle/Controller/FrontController.php"
-    type:     annotation
-    prefix:   /front
-
 # legacy routes
 main:
     path:     /main/{name}

+ 22 - 0
src/ChamiloLMS/CoreBundle/Resources/config/services.yml

@@ -1,4 +1,16 @@
 services:
+#    chamilolms.doctrine.entity_listener_resolver:
+#        class: ChamiloLMS\CoreBundle\Doctrine\EntityListenerResolver
+#        arguments: [ "@service_container" ]
+
+    chamilolms.entity_listener.course:
+        class: ChamiloLMS\CoreBundle\Entity\Listener\CourseListener
+        arguments: [ @chamilolms.tool_chain ]
+        tags:
+            - { name: doctrine.orm.entity_listener }
+
+#            - { name: doctrine.event_listener, event: prePersist }
+
     html_editor:
         class: ChamiloLMS\CoreBundle\Component\Editor\CkEditor\CkEditor
         arguments: [@translator, @router]
@@ -22,6 +34,12 @@ services:
         tags:
             - { name: kernel.event_subscriber }
 
+    listener.navbar_menu_listener:
+        class: ChamiloLMS\CoreBundle\EventListener\MenuListener
+        arguments: [@service_container]
+        tags:
+            - { name: kernel.event_listener, event: theme.sidebar_setup_menu_knp, method: onSetupMenu }
+
     listener.navbar_user_listener:
         class: ChamiloLMS\CoreBundle\EventListener\ShowUserListener
         arguments: [@service_container]
@@ -64,6 +82,10 @@ services:
 
     # Menus
 
+    chamilolms.menu.simple_menu:
+        class: ChamiloLMS\CoreBundle\Menu\SimpleMenuBuilder
+        arguments: [@service_container]
+
     chamilolms.corebundle.menu.main_menu_builder:
         class: ChamiloLMS\CoreBundle\Menu\MainMenuBuilder
         arguments: [@knp_menu.factory, @router]

+ 544 - 0
src/ChamiloLMS/CoreBundle/Resources/views/Calendar/month.html.twig

@@ -0,0 +1,544 @@
+<script>
+function checkLength( o, n, min, max ) {
+    if ( o.val().length > max || o.val().length < min ) {
+        o.addClass( "ui-state-error" );
+        /*updateTips( "Length of " + n + " must be between " +
+         min + " and " + max + "." );*/
+        return false;
+    } else {
+        return true;
+    }
+}
+function clean_user_select() {
+    //Cleans the selected attr
+    $("#users_to_send_id").val('').trigger("chosen:updated");
+    /*$('#users_to_send_id')
+     .find('option')
+     .removeAttr('selected')
+     .end();*/
+}
+
+var region_value = '{{ region_value }}';
+$(document).ready(function() {
+    var date = new Date();
+    var d = date.getDate();
+    var m = date.getMonth()+1;
+    var y = date.getFullYear();
+
+    $("#dialog-form").dialog({
+        autoOpen: false,
+        modal	: false,
+        width	: 580,
+        height	: 480,
+        zIndex: 20000 // added because of qtip2
+    });
+
+    $("#simple-dialog-form").dialog({
+        autoOpen: false,
+        modal	: false,
+        width	: 580,
+        height	: 480,
+        zIndex: 20000 // added because of qtip2
+    });
+
+    var title = $( "#title" ),
+            content = $( "#content" ),
+            allFields = $( [] ).add( title ).add( content ), tips = $(".validateTips");
+
+    $('#users_to_send_id').bind('change', function() {
+
+        var selected_counts = $("#users_to_send_id option:selected").size();
+
+        //alert(selected_counts);
+        /* if (selected_counts >= 1 && $("#users_to_send_id option[value='everyone']").attr('selected') == 'selected') {
+         clean_user_select();
+
+         $('#users_to_send_id option').eq(0).attr('selected', 'selected');
+         //deleting the everyone
+         $("#users_to_send_id").trigger("liszt:updated");
+         deleted_items = true;
+
+         }*/
+        //$("#users_to_send_id").trigger("chosen:updated");
+        /*
+         if (selected_counts >= 1) {
+         $('#users_to_send_id option').eq(0).removeAttr('selected');
+
+
+         }
+
+         */
+        //clean_user_select();
+        //$("#users_to_send_id").trigger("liszt:updated");
+        //alert($("#users_to_send_id option[value='everyone']").attr('selected'));
+        if ($("#users_to_send_id option[value='everyone']").attr('selected') == 'selected') {
+            //clean_user_select();
+            //$('#users_to_send_id option').eq(0).attr('selected', 'selected');
+            //$("#users_to_send_id").trigger("liszt:updated");
+        }
+    });
+
+    $.datepicker.setDefaults( $.datepicker.regional[region_value] );
+
+    var calendar = $('#calendar').fullCalendar({
+        header: {
+            left: 'today prev,next',
+            center: 'title',
+            right: 'month,agendaWeek,agendaDay, test'
+        },
+        {% if use_google_calendar == 1 %}
+        eventSources: [
+            // if you want to add more just add URL in this array
+            '{{ google_calendar_url }}',
+            {
+                className: 'gcal-event' // an option!
+            }
+        ],
+        {% endif %}
+
+        defaultView:    '{{ default_view }}',
+        buttonText: 	{{ button_text }},
+        monthNames: 	{{ month_names }},
+        monthNamesShort:{{ month_names_short }},
+        dayNames: 		{{ day_names }},
+        dayNamesShort: 	{{ day_names_short }},
+        firstHour: 8,
+        firstDay: 1,
+        selectable	: true,
+        selectHelper: true,
+
+        viewDisplay: function(view) {
+            /* When changing the view update the qtips */
+            var api = $('.qtip').qtip('api'); // Access the API of the first tooltip on the page
+            if (api) {
+                api.destroy();
+                //api.render();
+            }
+        },
+        // Add event
+        select: function(start, end, allDay, jsEvent, view) {
+            //Removing UTC stuff
+            var start_date = $.datepicker.formatDate("yy-mm-dd", start) + " " + start.toTimeString().substr(0, 8);
+            var end_date  = $.datepicker.formatDate("yy-mm-dd", end) + " " + end.toTimeString().substr(0, 8);
+
+            $('#visible_to_input').show();
+            $('#add_as_announcement_div').show();
+            $('#visible_to_read_only').hide();
+
+            // Cleans the selected attr
+            clean_user_select();
+
+            //Sets the 1st item selected by default
+            //$('#users_to_send_id option').eq(0).attr('selected', 'selected');
+
+            // Update chz-select
+            //$("#users_to_send_id").trigger("chosen:updated");
+
+            if ({{ can_add_events }} == 1) {
+                var url = '{{ web_agenda_ajax_url }}&a=add_event&start='+start_date+'&end='+end_date+'&all_day='+allDay+'&view='+view.name;
+                var start_date_value = $.datepicker.formatDate('{{ js_format_date }}', start);
+                var end_date_value  = $.datepicker.formatDate('{{ js_format_date }}', end);
+
+                $('#start_date').html(start_date_value + " " +  start.toTimeString().substr(0, 8));
+
+                if (view.name != 'month') {
+                    $('#start_date').html(start_date_value + " " +  start.toTimeString().substr(0, 8));
+                    if (start.toDateString() == end.toDateString()) {
+                        $('#end_date').html(' - '+end.toTimeString().substr(0, 8));
+                    } else {
+                        $('#end_date').html(' - '+start_date_value+" " + end.toTimeString().substr(0, 8));
+                    }
+                } else {
+                    $('#start_date').html(start_date_value);
+                    $('#end_date').html(' ');
+                }
+                $('#color_calendar').html('{{ type_label }}');
+                $('#color_calendar').removeClass('group_event');
+                $('#color_calendar').addClass('label_tag');
+                $('#color_calendar').addClass('{{ type_event_class }}');
+
+                allFields.removeClass("ui-state-error");
+                $("#dialog-form").dialog("open");
+                $("#dialog-form").dialog({
+                    buttons: {
+                        '{{ "Add" | trans }}' : function() {
+                            var bValid = true;
+                            bValid = bValid && checkLength(title, "title", 1, 255);
+                            //bValid = bValid && checkLength( content, "content", 1, 255 );
+
+                            var params = $("#add_event_form").serialize();
+                            $.ajax({
+                                url: url+'&'+params,
+                                success:function(data) {
+                                    var user = $('#users_to_send_id').val();
+                                    if (user) {
+                                        if (user.length > 1) {
+                                            user = 0;
+                                        } else {
+                                            user = user[0];
+                                        }
+                                        var user_length = String(user).length;
+                                        if (String(user).substring(0,1) == 'G') {
+                                            var user_id = String(user).substring(6,user_length);
+                                            var user_id = "G:"+user_id;
+                                        } else {
+                                            var user_id = String(user).substring(5,user_length);
+                                        }
+                                        var temp = "&user_id="+user_id;
+                                        var position =String(window.location).indexOf("&user");
+                                        var url_length = String(window.location).length;
+                                        var url = String(window.location).substring(0, position)+temp;
+
+                                        /*if (position > 0) {
+                                         window.location.replace(url);
+                                         } else {
+                                         url = String(window.location)+temp;
+                                         window.location.replace(url);
+                                         }*/
+                                    } else {
+                                        /* calendar.fullCalendar("refetchEvents");
+                                         calendar.fullCalendar("rerenderEvents");*/
+                                    }
+
+                                    calendar.fullCalendar("refetchEvents");
+                                    calendar.fullCalendar("rerenderEvents");
+
+                                    $("#dialog-form").dialog("close");
+                                }
+                            });
+                        }
+                    },
+                    close: function() {
+                        $("#title").attr('value', '');
+                        $("#content").attr('value', '');
+                    }
+                });
+
+                // Don't follow the link.
+                return false;
+
+                calendar.fullCalendar('unselect');
+                //Reload events
+                calendar.fullCalendar("refetchEvents");
+                calendar.fullCalendar("rerenderEvents");
+            }
+        },
+        eventRender: function(event, element) {
+            if (event.attachment) {
+                element.qtip({
+                    hide: {
+                        delay: 2000
+                    },
+                    content: event.attachment,
+                    position: { at:'top right' , my:'bottom right'},
+                }).removeData('qtip'); // this is an special hack to add multiple qtip in the same target
+            }
+            if (event.description) {
+                element.qtip({
+                    hide: {
+                        delay: 2000
+                    },
+                    content: event.description,
+                    position: { at:'top left' , my:'bottom left'}
+                });
+            }
+        },
+        eventClick: function(calEvent, jsEvent, view) {
+            //var start_date 	= Math.round(calEvent.start.getTime() / 1000);
+            var start_date = $.datepicker.formatDate("yy-mm-dd", calEvent.start) + " " + calEvent.start.toTimeString().substr(0, 8);
+
+            if (calEvent.allDay == 1) {
+                var end_date 	= '';
+            } else {
+                var end_date 	= '';
+                if (calEvent.end && calEvent.end != '') {
+                    //var end_date 	= Math.round(calEvent.end.getTime() / 1000);
+                    var end_date  = $.datepicker.formatDate("yy-mm-dd", calEvent.end) + " " + calEvent.end.toTimeString().substr(0, 8);
+                }
+            }
+
+            // Edit event.
+            if (calEvent.editable) {
+
+                $('#visible_to_input').hide();
+                $('#add_as_announcement_div').hide();
+
+                {% if type != 'admin' %}
+                $('#visible_to_read_only').show();
+                console.log(calEvent.sent_to);
+                $("#visible_to_read_only_users").html(calEvent.sent_to);
+                {% endif %}
+
+                $('#color_calendar').html('{{type_label}}');
+                $('#color_calendar').addClass('label_tag');
+                $('#color_calendar').removeClass('course_event');
+                $('#color_calendar').removeClass('personal_event');
+                $('#color_calendar').removeClass('group_event');
+                $('#color_calendar').addClass(calEvent.type+'_event');
+
+                my_start_month = calEvent.start.getMonth() +1;
+
+                $('#start_date').html(calEvent.start.getDate() +"/"+ my_start_month +"/"+calEvent.start.getFullYear());
+
+                if (end_date != '') {
+                    my_end_month = calEvent.end.getMonth() +1;
+                    $('#end_date').html(' '+calEvent.end.getDate() +"/"+ my_end_month +"/"+calEvent.end.getFullYear());
+                }
+
+                if ($("#title").parent().find('#title_edit').length == 0) {
+                    $("#title").parent().append('<div id="title_edit"></div>');
+                }
+
+                $("#title_edit").html(calEvent.title);
+
+                if ($("#content").parent().find('#content_edit').length == 0) {
+                    $("#content").parent().append('<div id="content_edit"></div>');
+                }
+
+                $("#content_edit").html(calEvent.description);
+
+                $("#title_edit").show();
+                $("#content_edit").show();
+
+                $("#title").hide();
+                $("#content").hide();
+
+                allFields.removeClass( "ui-state-error" );
+
+                $("#dialog-form").dialog("open");
+
+                var url = '{{ web_agenda_ajax_url }}&a=edit_event&id='+calEvent.id+'&start='+start_date+'&end='+end_date+'&all_day='+calEvent.allDay+'&view='+view.name;
+                var delete_url = '{{ web_agenda_ajax_url }}&a=delete_event&id='+calEvent.id;
+
+                $("#dialog-form").dialog({
+                    buttons: {
+                        '{{ "ExportiCalConfidential"|trans }}' : function() {
+                            url =  "{{ _p.web_main }}calendar/ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=confidential";
+                            window.location.href = url;
+                        },
+                        '{{ "ExportiCalPrivate"|trans }}': function() {
+                            url =  "{{ _p.web_main }}calendar/ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=private";
+                            window.location.href = url;
+                        },
+                        '{{ "ExportiCalPublic"|trans }}': function() {
+                            url =  "{{ _p.web_main }}calendar/ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=public";
+                            window.location.href = url;
+                        },
+                        {% if type == 'not_available' %}
+                        '{{ "Edit" | trans }}' : function() {
+                            var bValid = true;
+                            bValid = bValid && checkLength( title, "title", 1, 255 );
+
+                            var params = $("#add_event_form").serialize();
+                            $.ajax({
+                                url: url+'&'+params,
+                                success:function() {
+                                    calEvent.title 			= $("#title").val();
+                                    calEvent.start 			= calEvent.start;
+                                    calEvent.end 			= calEvent.end;
+                                    calEvent.allDay         = calEvent.allDay;
+                                    calEvent.description 	= $("#content").val();
+
+                                    calendar.fullCalendar('updateEvent',
+                                            calEvent,
+                                            true // make the event "stick"
+                                    );
+                                    $("#dialog-form").dialog("close");
+                                }
+                            });
+                        },
+                        {% endif %}
+
+                        '{{ "Edit"|trans }}' : function() {
+                            url =  "{{ _p.web_main }}calendar/agenda.php?action=edit&type=fromjs&id=" + calEvent.id+'&course_id='+calEvent.course_id+"";
+                            window.location.href = url;
+                            $("#dialog-form").dialog( "close" );
+                        },
+
+                        '{{ "Delete"|trans }}': function() {
+
+                            if (calEvent.parent_event_id || calEvent.has_children != '' ) {
+                                var newDiv = $(document.createElement('div'));
+                                //newDiv.html('{{ "" |trans }}');
+
+                                newDiv.dialog({
+                                    modal: true,
+                                    title: "{{ 'Confirmation' | trans }}"
+                                });
+
+                                var buttons = newDiv.dialog("option", "buttons");
+
+                                if (calEvent.has_children == '0') {
+                                    $.extend(buttons, {
+                                        '{{ "DeleteThisItem" | trans }}' : function() {
+                                            $.ajax({
+                                                url: delete_url,
+                                                success:function() {
+                                                    calendar.fullCalendar('removeEvents',
+                                                            calEvent
+                                                    );
+                                                    calendar.fullCalendar("refetchEvents");
+                                                    calendar.fullCalendar("rerenderEvents");
+                                                    $("#dialog-form").dialog( "close" );
+                                                    newDiv.dialog( "close" );
+                                                }
+                                            });
+                                        }
+                                    });
+                                    newDiv.dialog("option", "buttons", buttons);
+                                }
+
+                                var buttons = newDiv.dialog("option", "buttons");
+
+                                $.extend(buttons, {
+                                    '{{ "DeleteAllItems" | trans }}' : function() {
+                                        $.ajax({
+                                            url: delete_url+'&delete_all_events=1',
+                                            success:function() {
+                                                calendar.fullCalendar('removeEvents',
+                                                        calEvent
+                                                );
+                                                calendar.fullCalendar("refetchEvents");
+                                                calendar.fullCalendar("rerenderEvents");
+                                                $("#dialog-form").dialog( "close" );
+                                                newDiv.dialog( "close" );
+                                            }
+                                        });
+                                    }
+                                });
+                                newDiv.dialog("option", "buttons", buttons);
+
+                                return true;
+                            }
+
+                            $.ajax({
+                                url: delete_url,
+                                success:function() {
+                                    calendar.fullCalendar('removeEvents',
+                                            calEvent
+                                    );
+                                    calendar.fullCalendar("refetchEvents");
+                                    calendar.fullCalendar("rerenderEvents");
+                                    $("#dialog-form").dialog( "close" );
+                                }
+                            });
+                        }
+                    },
+                    close: function() {
+                        $("#title_edit").hide();
+                        $("#content_edit").hide();
+
+                        $("#title").show();
+                        $("#content").show();
+
+                        $("#title_edit").html('');
+                        $("#content_edit").html('');
+
+                        $("#title").attr('value', '');
+                        $("#content").attr('value', '');
+                    }
+                });
+            } else {
+                //Simple form
+                my_start_month = calEvent.start.getMonth() +1;
+                $('#simple_start_date').html(calEvent.start.getDate() +"/"+ my_start_month +"/"+calEvent.start.getFullYear());
+
+                if (end_date != '') {
+                    my_end_month = calEvent.end.getMonth() +1;
+                    $('#simple_start_date').html(calEvent.start.getDate() +"/"+ my_start_month +"/"+calEvent.start.getFullYear() +" - "+calEvent.start.toLocaleTimeString());
+                    $('#simple_end_date').html(' '+calEvent.end.getDate() +"/"+ my_end_month +"/"+calEvent.end.getFullYear() +" - "+calEvent.end.toLocaleTimeString());
+                }
+
+                $("#simple_title").html(calEvent.title);
+                $("#simple_content").html(calEvent.description);
+                $("#simple-dialog-form").dialog("open");
+                $("#simple-dialog-form").dialog({
+                    buttons: {
+                        '{{"ExportiCalConfidential"|trans}}' : function() {
+                            url =  "ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=confidential";
+                            window.location.href = url;
+
+                        },
+                        '{{"ExportiCalPrivate"|trans}}': function() {
+                            url =  "ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=private";
+                            window.location.href = url;
+                        },
+                        '{{"ExportiCalPublic"|trans}}': function() {
+                            url =  "ical_export.php?id=" + calEvent.id+'&course_id='+calEvent.course_id+"&class=public";
+                            window.location.href = url;
+                        }
+                    }
+                });
+            }
+        },
+        editable: true,
+        events: "{{web_agenda_ajax_url}}&a=get_events",
+        eventDrop: function(event, day_delta, minute_delta, all_day, revert_func) {
+            $.ajax({
+                url: '{{ web_agenda_ajax_url }}',
+                data: {
+                    a:'move_event', id: event.id, day_delta: day_delta, minute_delta: minute_delta
+                }
+            });
+        },
+        eventResize: function(event, day_delta, minute_delta, revert_func) {
+            $.ajax({
+                url: '{{ web_agenda_ajax_url }}',
+                data: {
+                    a:'resize_event', id: event.id, day_delta: day_delta, minute_delta: minute_delta
+                }
+            });
+        },
+        axisFormat: 'HH(:mm)',
+        timeFormat: 'HH:mm{ - HH:mm}',
+        loading: function(bool) {
+            if (bool) $('#loading').show();
+            else $('#loading').hide();
+        }
+    });
+});
+</script>
+{{ actions_div }}
+
+<div id="simple-dialog-form" style="display:none;">
+    <div style="width:500px">
+        <form name="form-simple" class="form-vertical">
+            <div class="control-group">
+                <label class="control-label">
+                    <b>{{ "Date" |trans}}</b>
+                </label>
+                <div class="controls">
+                    <span id="simple_start_date"></span>
+                    <span id="simple_end_date"></span>
+                </div>
+            </div>
+            <div class="control-group">
+                <label class="control-label">
+                    <b>{{ "Title" |trans}}</b>
+                </label>
+                <div class="controls">
+                    <div id="simple_title"></div>
+                </div>
+            </div>
+
+            <div class="control-group">
+                <label class="control-label">
+                    <b>{{ "Description" |trans}}</b>
+                </label>
+                <div class="controls">
+                    <div id="simple_content"></div>
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+
+<div id="dialog-form" style="display:none;">
+    <div style="width:500px">
+        {{ form_add }}
+    </div>
+</div>
+<div id="loading" style="margin-left:150px;position:absolute;display:none">
+    {{ "Loading"|trans }}...
+</div>
+<div id="calendar"></div>

+ 2 - 0
src/ChamiloLMS/CoreBundle/Resources/views/Index/index.html.twig

@@ -1,6 +1,8 @@
+{% extends "ChamiloLMSCoreBundle::main_layout.html.twig" %}
 {% block page_content %}
     {% autoescape false %}
     {{ content }}
+    {% include "@template_style/layout/hot_courses.tpl" %}
     {% endautoescape %}
 {% endblock %}
 

+ 0 - 1
src/ChamiloLMS/CoreBundle/Resources/views/Index/userportal.html.twig

@@ -1,4 +1,3 @@
-{#{% extends "ChamiloLMSCoreBundle::main_layout.html.twig" %}#}
 {%  block page_content  %}
     {% autoescape false %}
     {{ content }}

+ 8 - 0
src/ChamiloLMS/CourseBundle/ChamiloLMSCourseBundle.php

@@ -3,7 +3,15 @@
 namespace ChamiloLMS\CourseBundle;
 
 use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
 
+use ChamiloLMS\CourseBundle\DependencyInjection\Compiler\ToolCompilerClass;
 class ChamiloLMSCourseBundle extends Bundle
 {
+    public function build(ContainerBuilder $container)
+    {
+        parent::build($container);
+
+        $container->addCompilerPass(new ToolCompilerClass());
+    }
 }

+ 89 - 11
src/ChamiloLMS/CourseBundle/Controller/Home/HomeController.php

@@ -13,12 +13,13 @@ use ChamiloLMS\CoreBundle\Entity\CTool;
 use ChamiloLMS\CoreBundle\Form\CourseHomeToolType;
 use Doctrine\Common\Collections\Criteria;
 use Display;
+use CourseHome;
 use ChamiloLMS\CoreBundle\Entity\Course;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
 
 /**
  * Class HomeController
- * @package ChamiloLMS\CourseBundle\Controller\CourseHome
+ * @package ChamiloLMS\CourseBundle\Controller\Home
  * @author Julio Montoya <gugli100@gmail.com>
  * @Route("/")
  */
@@ -58,7 +59,7 @@ class HomeController extends ToolBaseController
             $editIcons = Display::url(
                 Display::return_icon('edit.png'),
                 $this->generateUrl(
-                    'chamilolms_course_home_coursehome_iconlist',
+                    'chamilolms_course_home_home_iconlist',
                     array(
                         'course' => api_get_course_id(),
                     )
@@ -92,18 +93,16 @@ class HomeController extends ToolBaseController
             }
         }
 
-        $script =  'activity.php';
         if (api_get_setting('homepage_view') == 'activity' || api_get_setting('homepage_view') == 'activity_big') {
-            $script =  'activity.php';
+            $result = $this->renderActivityView();
         } elseif (api_get_setting('homepage_view') == '2column') {
-            $script = '2column.php';
+            $result = $this->render2ColumnView();
         } elseif (api_get_setting('homepage_view') == '3column') {
-            $script = '3column.php';
+            $result = $this->render3ColumnView();
         } elseif (api_get_setting('homepage_view') == 'vertical_activity') {
-            $script = 'vertical_activity.php';
+            $result = $this->renderVerticalActivityView();
         }
 
-        $result = require_once api_get_path(SYS_CODE_PATH).'course_home/'.$script;
         $toolList = $result['tool_list'];
 
         $introduction = Display::return_introduction_section(
@@ -113,11 +112,11 @@ class HomeController extends ToolBaseController
         );
         $sessionInfo = null;
         if (api_get_setting('show_session_data') == 'true' && $sessionId) {
-            $sessionInfo = \CourseHome::show_session_data($sessionId);
+            $sessionInfo = CourseHome::show_session_data($sessionId);
         }
 
         /*$response = $this->render(
-            'ChamiloLMSCoreBundle:Tool:CourseHome/index.html.twig',
+            'ChamiloLMSCoreBundle:Tool:Home/index.html.twig',
             array(
                 'session_info' => $sessionInfo,
                 'icons' => $result['content'],
@@ -131,7 +130,7 @@ class HomeController extends ToolBaseController
         return new Response($response, 200, array());*/
 
         return $this->render(
-            'ChamiloLMSCourseBundle:CourseHome:index.html.twig',
+            'ChamiloLMSCourseBundle:Home:index.html.twig',
             array(
                 'session_info' => $sessionInfo,
                 'icons' => $result['content'],
@@ -143,6 +142,85 @@ class HomeController extends ToolBaseController
         );
     }
 
+    function return_block($title, $content)
+    {
+        $html = '<div class="page-header">
+                <h3>'.$title.'</h3>
+            </div>
+            '.$content.'</div>';
+        return $html;
+    }
+
+    private function renderActivityView()
+    {
+        $session_id = api_get_session_id();
+        $urlGenerator = $this->get('router');
+
+        $content = null;
+
+        // Start of tools for CourseAdmins (teachers/tutors)
+        $totalList = array();
+
+        if ($session_id == 0 && api_is_course_admin() && api_is_allowed_to_edit(null, true)) {
+            $list = CourseHome::get_tools_category(TOOL_AUTHORING);
+            $result = CourseHome::show_tools_category($urlGenerator, $list);
+            $content .= $this->return_block(get_lang('Authoring'), $result['content']);
+
+            $totalList = $result['tool_list'];
+
+            $list = CourseHome::get_tools_category(TOOL_INTERACTION);
+            $list2 = CourseHome::get_tools_category(TOOL_COURSE_PLUGIN);
+            $list = array_merge($list, $list2);
+            $result =  CourseHome::show_tools_category($urlGenerator, $list);
+            $totalList = array_merge($totalList, $result['tool_list']);
+
+            $content .= $this->return_block(get_lang('Interaction'), $result['content']);
+
+            $list = CourseHome::get_tools_category(TOOL_ADMIN_PLATFORM);
+            $totalList = array_merge($totalList, $list);
+            $result = CourseHome::show_tools_category($urlGenerator, $list);
+            $totalList = array_merge($totalList, $result['tool_list']);
+            $content .= $this->return_block(get_lang('Administration'), $result['content']);
+
+        } elseif (api_is_coach()) {
+
+            $content .=  '<div class="row">';
+            $list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
+            $content .= CourseHome::show_tools_category($urlGenerator, $result['content']);
+            $totalList = array_merge($totalList, $result['tool_list']);
+            $content .= '</div>';
+        } else {
+            $list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
+            if (count($list) > 0) {
+                $content .= '<div class="row">';
+                $result = CourseHome::show_tools_category($urlGenerator, $list);
+                $content .= $result['content'];
+                $totalList = array_merge($totalList, $result['tool_list']);
+                $content .= '</div>';
+            }
+        }
+
+        return array(
+            'content' => $content,
+            'tool_list' => $totalList
+        );
+    }
+
+    private function render2ColumnView()
+    {
+
+    }
+
+    private function render3ColumnView()
+    {
+
+    }
+
+    private function renderVerticalActivityView()
+    {
+
+    }
+
     /**
      * @return array
      */

+ 33 - 0
src/ChamiloLMS/CourseBundle/DependencyInjection/Compiler/ToolCompilerClass.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace ChamiloLMS\CourseBundle\DependencyInjection\Compiler;;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Class ToolCompilerClass
+ * @package ChamiloLMS\CourseBundle\DependencyInjection\Compiler
+ */
+class ToolCompilerClass implements CompilerPassInterface
+{
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition('chamilolms.tool_chain')) {
+            return;
+        }
+
+        $definition = $container->getDefinition(
+            'chamilolms.tool_chain'
+        );
+
+        $taggedServices = $container->findTaggedServiceIds(
+            'chamilolm.course.tool'
+        );
+
+        foreach ($taggedServices as $id => $attributes) {
+            $definition->addMethodCall('addTool', array(new Reference($id)));
+        }
+    }
+}

+ 4 - 1
src/ChamiloLMS/CourseBundle/Entity/CTool.php

@@ -121,7 +121,7 @@ class CTool
     private $description;
 
     /**
-     * @ORM\ManyToOne(targetEntity="ChamiloLMS\CoreBundle\Entity\Course")
+     * @ORM\ManyToOne(targetEntity="ChamiloLMS\CoreBundle\Entity\Course", inversedBy="tools")
      * @ORM\JoinColumn(name="c_id", referencedColumnName="id")
      */
     private $course;
@@ -132,6 +132,9 @@ class CTool
      */
     public function __construct()
     {
+        // Default values
+        $this->id = 0;
+        $this->sessionId = 0;
     }
 
     /**

+ 0 - 0
src/ChamiloLMS/CourseBundle/Resources/config/routing.yml


+ 19 - 0
src/ChamiloLMS/CourseBundle/Resources/config/services.yml

@@ -0,0 +1,19 @@
+parameters:
+    tool_chain.class: ChamiloLMS\CourseBundle\ToolChain
+services:
+    chamilolms.tool_chain:
+        class: %tool_chain.class%
+
+    chamilolms.coursebundle.tool.calendar.class:
+        class: ChamiloLMS\CourseBundle\Tool\Calendar
+        arguments:
+            - calendar
+        tags:
+            - { name: chamilolm.course.tool }
+
+    chamilolms.coursebundle.tool.document.class:
+        class: ChamiloLMS\CourseBundle\Tool\Document
+        arguments:
+            - document
+        tags:
+            - { name: chamilolm.course.tool }

+ 0 - 0
src/ChamiloLMS/CourseBundle/Resources/views/CourseHome/add.tpl → src/ChamiloLMS/CourseBundle/Resources/views/Home/add.tpl


+ 0 - 0
src/ChamiloLMS/CourseBundle/Resources/views/CourseHome/edit.tpl → src/ChamiloLMS/CourseBundle/Resources/views/Home/edit.tpl


+ 2 - 0
src/ChamiloLMS/CourseBundle/Resources/views/CourseHome/index.html.twig → src/ChamiloLMS/CourseBundle/Resources/views/Home/index.html.twig

@@ -1,3 +1,5 @@
+{% extends "ChamiloLMSCoreBundle::main_layout.html.twig" %}
+
 {% block page_content %}
 
 {% autoescape false %}

+ 0 - 0
src/ChamiloLMS/CourseBundle/Resources/views/CourseHome/list.tpl → src/ChamiloLMS/CourseBundle/Resources/views/Home/list.tpl


+ 35 - 0
src/ChamiloLMS/CourseBundle/Tool/BaseTool.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace ChamiloLMS\CourseBundle\Tool;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+
+
+abstract class BaseTool implements ToolInterface
+{
+    protected $name;
+    protected $link;
+
+    /**
+     * @param string $name
+     */
+    public function __construct($name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setDefaultSettings(OptionsResolverInterface $resolver)
+    {
+
+    }
+}

+ 36 - 0
src/ChamiloLMS/CourseBundle/Tool/Calendar.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace ChamiloLMS\CourseBundle\Tool;
+
+/**
+ * Class Calendar
+ * @package ChamiloLMS\CourseBundle\Tool
+ */
+class Calendar extends BaseTool
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'Calendar';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLink()
+    {
+        return 'calendar/agenda.php';
+    }
+
+    public function getTarget()
+    {
+        return '_self';
+    }
+
+    public function getCategory()
+    {
+        return 'authoring';
+    }
+}

+ 37 - 0
src/ChamiloLMS/CourseBundle/Tool/Document.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace ChamiloLMS\CourseBundle\Tool;
+
+/**
+ * Class Calendar
+ * @package ChamiloLMS\CourseBundle\Tool
+ */
+class Document extends BaseTool
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'Document';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLink()
+    {
+        return 'document/document.php';
+    }
+
+    public function getTarget()
+    {
+        return '_self';
+    }
+
+    public function getCategory()
+    {
+        return 'authoring';
+    }
+
+}

+ 36 - 0
src/ChamiloLMS/CourseBundle/Tool/ToolInterface.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace ChamiloLMS\CourseBundle\Tool;
+
+/**
+ * Interface ToolInterface
+ * @package ChamiloLMS\CourseBundle\Tool
+ */
+interface ToolInterface
+{
+    /**
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * @return string
+     */
+    public function getLink();
+
+    /**
+     * @return string
+     */
+    public function getTarget();
+
+    /**
+     * @return string
+     */
+    public function getCategory();
+
+    /**
+     * @return string
+     */
+    //public function getName();
+
+}

+ 36 - 0
src/ChamiloLMS/CourseBundle/ToolChain.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace ChamiloLMS\CourseBundle;
+
+/**
+ * Class ToolChain
+ * @package ChamiloLMS\CourseBundle
+ */
+class ToolChain
+{
+    protected $tools;
+
+    /**
+     *
+     */
+    public function __construct()
+    {
+        $this->tools = array();
+    }
+
+    /**
+     * @param $tool
+     */
+    public function addTool($tool)
+    {
+        $this->tools[] = $tool;
+    }
+
+    /**
+     * @return array
+     */
+    public function getTools()
+    {
+        return $this->tools;
+    }
+}

+ 46 - 0
src/ChamiloLMS/InstallerBundle/ChamiloLMSInstallerBundle.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace ChamiloLMS\InstallerBundle;
+
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\Console\Application;
+use ChamiloLMS\InstallerBundle\Command\InstallCommand;
+
+/**
+ * Class ChamiloLMSInstallerBundle
+ * @package ChamiloLMS\InstallerBundle
+ */
+class ChamiloLMSInstallerBundle extends Bundle
+{
+    /**
+     * @param Application $application
+     */
+    public function registerCommands(Application $application)
+    {
+        $application->addCommands(array(
+            // DBAL Commands.
+            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
+            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
+
+            // Migrations Commands.
+            new \Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand(),
+            new \Doctrine\DBAL\Migrations\Tools\Console\Command\ExecuteCommand(),
+            new \Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand(),
+            new \Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand(),
+            new \Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand(),
+            new \Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand(),
+
+            // Chash commands.
+            //new UpgradeCommand(),
+            new InstallCommand(),
+            new \Chash\Command\Installation\InstallCommand(),
+
+            new \Chash\Command\Files\CleanCoursesFilesCommand(),
+            new \Chash\Command\Files\CleanTempFolderCommand(),
+            new \Chash\Command\Files\CleanConfigFilesCommand(),
+            new \Chash\Command\Files\MailConfCommand(),
+            new \Chash\Command\Files\SetPermissionsAfterInstallCommand(),
+            new \Chash\Command\Files\GenerateTempFileStructureCommand()
+        ));
+    }
+}

+ 186 - 0
src/ChamiloLMS/InstallerBundle/Command/InstallCommand.php

@@ -0,0 +1,186 @@
+<?php
+
+namespace ChamiloLMS\InstallerBundle\Command;
+
+use RuntimeException;
+use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\ArrayInput;
+
+/**
+ * Class InstallCommand
+ * @package ChamiloLMS\InstallerBundle\Command
+ */
+class InstallCommand extends ContainerAwareCommand
+{
+    protected function configure()
+    {
+        $this
+            ->setName('chamilo:install')
+            ->setDescription('Chamilo installer.')
+        ;
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return int|null|void
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $output->writeln('<info>Installing Chamilo.</info>');
+        $output->writeln('');
+
+        $this
+            ->checkStep($input, $output)
+            ->setupStep($input, $output)
+        ;
+
+        $output->writeln('<info>Chamilo has been successfully installed.</info>');
+    }
+
+    /**
+     * @param string $command
+     * @param OutputInterface $output
+     * @param array $arguments
+     * @return $this
+     * @throws \Exception
+     */
+    protected function runCommand($command, OutputInterface $output, $arguments = array())
+    {
+        $arguments['command'] = $command;
+        $input = new ArrayInput($arguments);
+
+        $this
+            ->getApplication()
+            ->find($command)
+            ->run($input, $output)
+        ;
+
+        return $this;
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return $this
+     */
+    protected function checkStep(InputInterface $input, OutputInterface $output)
+    {
+        $output->writeln('<info>Checking system requirements.</info>');
+
+        $fulfilled = true;
+
+        // $rootDir = $this->getContainer()->get('kernel')->getRealRootDir();
+
+        $this->runCommand('doctrine:database:drop', $output, array('--force' => true));
+
+        // Make sure we close the original connection because it lost the reference to the database
+        $connection = $this->getApplication()->getKernel()->getContainer()->get('doctrine')->getConnection();
+
+        if ($connection->isConnected()) {
+            $connection->close();
+        }
+
+        $this->runCommand('cache:warmup', $output, array('--env' => 'prod', '--no-debug' => true));
+
+        $this
+            ->runCommand('doctrine:database:create', $output)
+            ->runCommand('doctrine:schema:create', $output)
+            //->runCommand('doctrine:phpcr:repository:init', $input, $output)
+            //->runCommand('chash:chamilo_install', $inputToInstall, $output)
+            ->runCommand('assets:install', $output)
+
+            //->runCommand('assetic:dump', $input, $output)
+        ;
+
+        if (!$fulfilled) {
+            throw new RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.');
+        }
+
+        $output->writeln('');
+
+        return $this;
+    }
+
+    protected function setupStep(InputInterface $input, OutputInterface $output)
+    {
+        $output->writeln('<info>Setting up database.</info>');
+
+        //$this->setupDatabase($input, $output);
+
+        //if ($this->getHelperSet()->get('dialog')->askConfirmation($output, '<question>Load fixtures (Y/N)?</question>', false)) {
+        $this->setupFixtures($input, $output);
+        //}
+
+        $output->writeln('');
+        $output->writeln('<info>Administration setup.</info>');
+
+        $this->setupAdmin($output);
+
+        $this->runCommand('sonata:page:update-core-routes', $output, array('--site' => 'all'));
+        $this->runCommand('sonata:page:create-snapshots', $output, array('--site' => 'all'));
+
+        $output->writeln('');
+
+        return $this;
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     */
+    protected function setupDatabase(InputInterface $input, OutputInterface $output)
+    {
+        $this
+            ->runCommand('doctrine:database:create', $input, $output)
+            ->runCommand('doctrine:schema:create', $input, $output)
+            //->runCommand('doctrine:phpcr:repository:init', $input, $output)
+            ->runCommand('assets:install', $input, $output)
+            //->runCommand('assetic:dump', $input, $output)
+        ;
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     */
+    protected function setupFixtures(InputInterface $input, OutputInterface $output)
+    {
+        $this
+            ->runCommand(
+                'doctrine:fixtures:load',
+                $output,
+                array('--no-interaction' => true)
+            )
+            //->runCommand('doctrine:phpcr:fixtures:load', $input, $output)
+        ;
+    }
+
+    /**
+     * @param OutputInterface $output
+     */
+    protected function setupAdmin(OutputInterface $output)
+    {
+        $dialog = $this->getHelperSet()->get('dialog');
+        //$user = new \Application\Sonata\UserBundle\Entity\User();
+        $em = $this->getApplication()->getKernel()->getContainer()->get('doctrine')->getManager();
+        /** @var \Application\Sonata\UserBundle\Entity\User $user */
+        $user = $em->getRepository('ApplicationSonataUserBundle:User')->findOneById(1);
+
+        $user->setUsername($dialog->ask($output, '<question>Username</question>(admin):', 'admin'));
+        $user->setPlainPassword($dialog->ask($output, '<question>Password</question>(admin):', 'admin'));
+
+        $user->setFirstname($dialog->ask($output, '<question>Firstname</question>(Jane):', 'Jane'));
+        $user->setLastname($dialog->ask($output, '<question>Lastname</question>(Doe):', 'Doe'));
+        $user->setEmail($dialog->ask($output, '<question>Email</question>(admin@example.org):', 'admin@example.org'));
+        $user->setEnabled(true);
+        $user->addRole('ROLE_SUPER_ADMIN');
+
+        $em = $this->getContainer()->get('doctrine.orm.entity_manager');
+        $em->persist($user);
+        $em->flush();
+    }
+
+}

+ 17 - 86
tests/doctrine_console/cli-config.php

@@ -8,114 +8,45 @@ use Doctrine\Common\Annotations\AnnotationReader;
 use Doctrine\Common\Annotations\AnnotationRegistry;
 use Symfony\Component\Yaml\Parser;
 
-AnnotationRegistry::registerFile(api_get_path(SYS_PATH)."vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
+$sysPath = __DIR__."/../../";
+AnnotationRegistry::registerFile($sysPath."vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
 $reader = new AnnotationReader();
 
-$driverImpl = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, array(api_get_path(SYS_PATH)."tests/doctrine_console/mapping"));
+$driverImpl = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver(
+    $reader,
+    array($sysPath."tests/doctrine_console/mapping")
+);
 
 $config->setMetadataDriverImpl($driverImpl);
 $config->setProxyDir(__DIR__ . '/Proxies');
 $config->setProxyNamespace('Proxies');
 
-$courseList = CourseManager::get_real_course_list();
-//$courseList = array();
-
-$configurationPath = api_get_path(SYS_PATH).'main/inc/conf/';
-$newConfigurationFile = $configurationPath.'configuration.yml';
-
-if (is_file($newConfigurationFile) && file_exists($newConfigurationFile)) {
-    $yaml = new Parser();
-    $_configuration = $yaml->parse(file_get_contents($newConfigurationFile));
-}
-
-$connectionOptions = array();
-
-if (!empty($courseList)) {
-
-    $dbPrefix = isset($_configuration['db_prefix']) && !empty($_configuration['db_prefix']) ? $_configuration['db_prefix'].Database::get_database_glue() : null;
-    foreach ($courseList as $course) {
-        $connectionOptions['_chamilo_course_'.$course['db_name']] = array(
-            'driver'    => 'pdo_mysql',
-            'dbname'    => $dbPrefix.$course['db_name'],
-            'user'      => $_configuration['db_user'],
-            'password'  => $_configuration['db_password'],
-            'host'      => $_configuration['db_host'],
-        );
-    }
-}
-
-if (isset($_configuration['main_database'])) {
-    $connectionOptions['main_database'] = array(
-        'driver'    => 'pdo_mysql',
-        'dbname'    => $_configuration['main_database'],
-        'user'      => $_configuration['db_user'],
-        'password'  => $_configuration['db_password'],
-        'host'      => $_configuration['db_host'],
-    );
-}
-
-if (isset($_configuration['statistics_database'])) {
-    $connectionOptions['statistics_database'] = array(
-        'driver'    => 'pdo_mysql',
-        'dbname'    => $_configuration['statistics_database'],
-        'user'      => $_configuration['db_user'],
-        'password'  => $_configuration['db_password'],
-        'host'      => $_configuration['db_host'],
-    );
-} else {
-    if (isset($_configuration['main_database'])) {
-        $connectionOptions['statistics_database'] = $connectionOptions['main_database'];
-    }
-}
-
-if (isset($_configuration['user_personal_database'])) {
-    $connectionOptions['user_personal_database'] = array(
-        'driver'    => 'pdo_mysql',
-        'dbname'    => $_configuration['user_personal_database'],
-        'user'      => $_configuration['db_user'],
-        'password'  => $_configuration['db_password'],
-        'host'      => $_configuration['db_host'],
-    );
-} else {
-    if (isset($_configuration['main_database'])) {
-        $connectionOptions['user_personal_database'] = $connectionOptions['main_database'];
-    }
-}
-
 $defaultConnection = array(
-    'driver' => 'pdo_mysql'
+    'driver'    => 'pdo_mysql',
+    'dbname'    => 'chamilo',
+    'user'      => 'root',
+    'password'  => 'root',
+    'host'      => 'localhost',
 );
 
-if (isset($_configuration['main_database'])) {
-    $defaultConnection = array(
-        'driver'    => 'pdo_mysql',
-        'dbname'    => $_configuration['main_database'],
-        'user'      => $_configuration['db_user'],
-        'password'  => $_configuration['db_password'],
-        'host'      => $_configuration['db_host'],
-    );
-}
-
 $em = \Doctrine\ORM\EntityManager::create($defaultConnection, $config);
 
 //Fixes some errors
 $platform = $em->getConnection()->getDatabasePlatform();
 $platform->registerDoctrineTypeMapping('enum', 'string');
 $platform->registerDoctrineTypeMapping('set', 'string');
-
+ \Doctrine\DBAL\Types\Type::addType('json', 'Sonata\Doctrine\Types\JsonType');
 $helpers = array(
     'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
     'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em),
     'configuration' => new \Chash\Helpers\ConfigurationHelper()
 );
 
-use Doctrine\DBAL\DriverManager;
-$multipleEM = array();
-foreach ($connectionOptions as $name => $connection) {
-    $em = \Doctrine\ORM\EntityManager::create($connection, $config);
-    //$helpers[$name] = new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em);
-    $helpers[$name] = new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection());
-}
+$em = \Doctrine\ORM\EntityManager::create($defaultConnection, $config);
+
+use Doctrine\ORM\Tools\Console\ConsoleRunner;
+return ConsoleRunner::createHelperSet($em);
+
 
 /*
 To generate doctrine2 entities you must: