Browse Source

Updating vendors + files from 1.10

Julio Montoya 11 years ago
parent
commit
261ca3114d
100 changed files with 5122 additions and 0 deletions
  1. 99 0
      main/inc/Entity/Role.php
  2. 1105 0
      main/inc/lib/agenda.lib.php
  3. 6 0
      main/template/default/admin/administrator/role/add.tpl
  4. 6 0
      main/template/default/admin/administrator/role/edit.tpl
  5. 8 0
      main/template/default/admin/administrator/role/list.tpl
  6. 6 0
      main/template/default/auth/login.tpl
  7. 143 0
      src/ChamiloLMS/Command/Translation/ExportLanguagesCommand.php
  8. 109 0
      src/ChamiloLMS/Controller/Admin/Administrator/RoleController.php
  9. 294 0
      src/ChamiloLMS/Controller/BaseController.php
  10. 32 0
      src/ChamiloLMS/Form/RoleType.php
  11. 71 0
      src/ChamiloLMS/Provider/ReflectionControllerProvider.php
  12. 153 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php
  13. 92 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php
  14. 30 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php
  15. 129 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php
  16. 129 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php
  17. 210 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php
  18. 212 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php
  19. 67 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php
  20. 95 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php
  21. 98 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php
  22. 27 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php
  23. 27 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php
  24. 75 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php
  25. 27 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php
  26. 27 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php
  27. 18 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php
  28. 24 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php
  29. 27 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php
  30. 30 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php
  31. 0 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json
  32. 199 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md
  33. 17 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt
  34. 104 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml
  35. 0 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json
  36. 388 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md
  37. 22 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt
  38. 181 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml
  39. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json
  40. 8 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md
  41. 7 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt
  42. 12 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml
  43. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json
  44. 30 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md
  45. 11 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt
  46. 18 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml
  47. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json
  48. 7 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md
  49. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt
  50. 5 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml
  51. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json
  52. 7 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md
  53. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt
  54. 5 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml
  55. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json
  56. 7 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md
  57. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt
  58. 7 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml
  59. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json
  60. 0 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md
  61. 0 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt
  62. 5 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml
  63. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json
  64. 9 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md
  65. 2 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt
  66. 10 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml
  67. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json
  68. 11 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md
  69. 2 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt
  70. 9 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml
  71. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json
  72. 21 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md
  73. 5 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt
  74. 14 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml
  75. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json
  76. 9 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md
  77. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt
  78. 4 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml
  79. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json
  80. 9 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md
  81. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt
  82. 7 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml
  83. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json
  84. 9 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md
  85. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt
  86. 5 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml
  87. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json
  88. 9 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md
  89. 1 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt
  90. 5 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml
  91. 136 0
      vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php
  92. 12 0
      vendor/igorw/config-service-provider/.travis.yml
  93. 42 0
      vendor/igorw/config-service-provider/CHANGELOG.md
  94. 37 0
      vendor/igorw/config-service-provider/src/Igorw/Silex/ChainConfigDriver.php
  95. 9 0
      vendor/igorw/config-service-provider/src/Igorw/Silex/ConfigDriver.php
  96. 43 0
      vendor/igorw/config-service-provider/src/Igorw/Silex/JsonConfigDriver.php
  97. 18 0
      vendor/igorw/config-service-provider/src/Igorw/Silex/PhpConfigDriver.php
  98. 23 0
      vendor/igorw/config-service-provider/src/Igorw/Silex/TomlConfigDriver.php
  99. 22 0
      vendor/igorw/config-service-provider/src/Igorw/Silex/YamlConfigDriver.php
  100. 204 0
      vendor/igorw/config-service-provider/tests/integration/ConfigServiceProviderTest.php

+ 99 - 0
main/inc/Entity/Role.php

@@ -0,0 +1,99 @@
+<?php
+namespace Entity;
+
+use Symfony\Component\Security\Core\Role\Role as SymfonyRole;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * @ORM\Table(name="roles")
+ * @ORM\Entity()
+ */
+class Role extends SymfonyRole
+{
+    /**
+     * @ORM\Column(name="id", type="integer")
+     * @ORM\Id()
+     * @ORM\GeneratedValue(strategy="AUTO")
+     */
+    private $id;
+
+    /**
+     * @ORM\Column(name="name", type="string", length=255)
+     */
+    private $name;
+
+    /**
+     * @ORM\Column(name="role", type="string", length=255, unique=true)
+     */
+    private $role;
+
+    /**
+     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
+     * @ORM\JoinTable(name="users_roles",
+     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="user_id")})
+     */
+    private $users;
+
+    public function __construct()
+    {
+        $this->users = new ArrayCollection();
+    }
+
+    /**
+     * @see RoleInterface
+     */
+    public function getRole()
+    {
+        return $this->role;
+    }
+
+    /**
+     * Get id
+     *
+     * @return integer
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+     /**
+     * Set name
+     *
+     * @param string $name
+     * @return Role
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+
+        return $this;
+    }
+
+
+    /**
+     * Get name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+     /**
+     * Set name
+     *
+     * @param string $name
+     * @return Role
+     */
+    public function setRole($name)
+    {
+        $this->name = $name;
+
+        return $this;
+    }
+
+
+}

+ 1105 - 0
main/inc/lib/agenda.lib.php

@@ -0,0 +1,1105 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ * @author: Julio Montoya <gugli100@gmail.com>
+ * Class Agenda
+ * @todo move this in main/inc/lib and update composer autoload
+ */
+class Agenda
+{
+    public $events = array();
+    public $type = 'personal';
+
+    /**
+     *
+     */
+    public function __construct()
+    {
+        //Table definitions
+        $this->tbl_global_agenda   = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
+        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
+        $this->tbl_course_agenda   = Database::get_course_table(TABLE_AGENDA);
+
+        // Setting the course object if we are in a course
+        $this->course = null;
+        $course_info  = api_get_course_info();
+        if (!empty($course_info)) {
+            $this->course = $course_info;
+        }
+
+        $this->events = array();
+
+        //Event colors
+        $this->event_platform_color = 'red'; //red
+        $this->event_course_color   = '#458B00'; //green
+        $this->event_group_color    = '#A0522D'; //siena
+        $this->event_session_color  = '#00496D'; // kind of green
+        $this->event_personal_color = 'steel blue'; //steel blue
+    }
+
+    /**
+     * Agenda type: personal, admin or course
+     * @param string $type
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+    }
+
+    /**
+     * Sets course info
+     * @param array $course_info
+     */
+    public function set_course($course_info)
+    {
+        $this->course = $course_info;
+    }
+
+    /**
+     *
+     * Adds an event to the calendar
+     *
+     * @param   string  start datetime format: 2012-06-14 09:00:00
+     * @param   string  end datetime format: 2012-06-14 09:00:00
+     * @param   string  all day (true, false)
+     * @param   string  view agendaDay, agendaWeek, month @todo seems not to be used
+     * @param   string  title
+     * @param   string  content
+     * @param   array   users to send array('everyone') or a list of user ids
+     * @param   bool    add event as a *course* announcement
+     *
+     */
+    public function add_event(
+        $start,
+        $end,
+        $all_day,
+        $view,
+        $title,
+        $content,
+        $users_to_send = array(),
+        $add_as_announcement = false
+    ) {
+        $start   = api_get_utc_datetime($start);
+        $end     = api_get_utc_datetime($end);
+        $all_day = isset($all_day) && $all_day == 'true' ? 1 : 0;
+
+        $attributes = array();
+        $id         = null;
+        switch ($this->type) {
+            case 'personal':
+                $attributes['user']    = api_get_user_id();
+                $attributes['title']   = $title;
+                $attributes['text']    = $content;
+                $attributes['date']    = $start;
+                $attributes['enddate'] = $end;
+                $attributes['all_day'] = $all_day;
+                $id                    = Database::insert($this->tbl_personal_agenda, $attributes);
+                break;
+            case 'course':
+                $attributes['title']      = $title;
+                $attributes['content']    = $content;
+                $attributes['start_date'] = $start;
+                $attributes['end_date']   = $end;
+                $attributes['all_day']    = $all_day;
+                $attributes['session_id'] = api_get_session_id();
+                $attributes['c_id']       = $this->course['real_id'];
+
+                //simple course event
+                $id = Database::insert($this->tbl_course_agenda, $attributes);
+
+                if ($id) {
+                    $group_id = api_get_group_id();
+
+                    if ((!is_null($users_to_send)) or (!empty($group_id))) {
+                        $send_to = self::separate_users_groups($users_to_send);
+                        if (isset($send_to['everyone']) && $send_to['everyone']) {
+                            api_item_property_update(
+                                $this->course,
+                                TOOL_CALENDAR_EVENT,
+                                $id,
+                                "AgendaAdded",
+                                api_get_user_id(),
+                                $group_id,
+                                '',
+                                $start,
+                                $end
+                            );
+                        } else {
+                            // storing the selected groups
+                            if (isset($send_to['groups']) && is_array($send_to['groups'])) {
+                                foreach ($send_to['groups'] as $group) {
+                                    api_item_property_update(
+                                        $this->course,
+                                        TOOL_CALENDAR_EVENT,
+                                        $id,
+                                        "AgendaAdded",
+                                        api_get_user_id(),
+                                        $group,
+                                        0,
+                                        $start,
+                                        $end
+                                    );
+                                }
+                            }
+
+                            // storing the selected users
+                            if (isset($send_to['groups']) && is_array($send_to['users'])) {
+                                foreach ($send_to['users'] as $to_user_id) {
+                                    api_item_property_update(
+                                        $this->course,
+                                        TOOL_CALENDAR_EVENT,
+                                        $id,
+                                        "AgendaAdded",
+                                        api_get_user_id(),
+                                        $group_id,
+                                        $to_user_id,
+                                        $start,
+                                        $end
+                                    );
+                                }
+                            }
+                        }
+                    }
+
+                    if (isset($add_as_announcement) && !empty($add_as_announcement)) {
+                        self::store_agenda_item_as_announcement($id, $users_to_send);
+                    }
+                }
+                break;
+            case 'admin':
+                if (api_is_platform_admin()) {
+                    $attributes['title']         = $title;
+                    $attributes['content']       = $content;
+                    $attributes['start_date']    = $start;
+                    $attributes['end_date']      = $end;
+                    $attributes['all_day']       = $all_day;
+                    $attributes['access_url_id'] = api_get_current_access_url_id();
+                    $id                          = Database::insert($this->tbl_global_agenda, $attributes);
+                }
+                break;
+        }
+
+        return $id;
+    }
+
+
+    /**
+     * @param int id
+     * @param array sent to
+     **/
+
+    public function store_agenda_item_as_announcement($item_id, $sent_to = array())
+    {
+        $table_agenda = Database::get_course_table(TABLE_AGENDA);
+        $course_id    = api_get_course_int_id();
+
+        //check params
+        if (empty($item_id) or $item_id != strval(intval($item_id))) {
+            return -1;
+        }
+        //get the agenda item
+
+        $item_id = Database::escape_string($item_id);
+        $sql     = "SELECT * FROM $table_agenda WHERE c_id = $course_id AND id = ".$item_id;
+        $res     = Database::query($sql);
+
+        if (Database::num_rows($res) > 0) {
+            $row = Database::fetch_array($res, 'ASSOC');
+
+            //Sending announcement
+            if (!empty($sent_to)) {
+                $id = AnnouncementManager::add_announcement(
+                    $row['title'],
+                    $row['content'],
+                    $sent_to,
+                    null,
+                    null,
+                    $row['end_date']
+                );
+                AnnouncementManager::send_email($id);
+            }
+
+            return $id;
+        }
+
+        return -1;
+    }
+
+    /**
+     * Edits an event
+     *
+     * @param int       event id
+     * @param string    start datetime format: 2012-06-14 09:00:00
+     * @param string    end datetime format: 2012-06-14 09:00:00
+     * @param int       event is all day? 1|0
+     * @param string    view
+     * @param string    event title
+     * @param string    event content
+     */
+    public function edit_event($id, $start, $end, $all_day, $view, $title, $content)
+    {
+        $start = api_get_utc_datetime($start);
+
+        if ($all_day == '0') {
+            $end = api_get_utc_datetime($end);
+        }
+        $all_day = isset($all_day) && $all_day == '1' ? 1 : 0;
+
+        $attributes = array();
+
+        switch ($this->type) {
+            case 'personal':
+                $eventInfo = $this->get_event($id);
+                if ($eventInfo['user'] != api_get_user_id()) {
+                    break;
+                }
+                $attributes['title']   = $title;
+                $attributes['text']    = $content;
+                $attributes['date']    = $start;
+                $attributes['enddate'] = $end;
+                Database::update($this->tbl_personal_agenda, $attributes, array('id = ?' => $id));
+                break;
+            case 'course':
+                $course_id = api_get_course_int_id();
+                if (!empty($course_id) && api_is_allowed_to_edit(null, true)) {
+                    $attributes['title']      = $title;
+                    $attributes['content']    = $content;
+                    $attributes['start_date'] = $start;
+                    $attributes['end_date']   = $end;
+                    $attributes['all_day']    = $all_day;
+                    Database::update(
+                        $this->tbl_course_agenda,
+                        $attributes,
+                        array('id = ? AND c_id = ?' => array($id, $course_id))
+                    );
+                }
+                break;
+            case 'admin':
+                if (api_is_platform_admin()) {
+                    $attributes['title']      = $title;
+                    $attributes['content']    = $content;
+                    $attributes['start_date'] = $start;
+                    $attributes['end_date']   = $end;
+                    Database::update($this->tbl_global_agenda, $attributes, array('id = ?' => $id));
+                }
+                break;
+        }
+    }
+
+    /**
+     * @param int $id
+     */
+    public function delete_event($id)
+    {
+        switch ($this->type) {
+            case 'personal':
+                $eventInfo = $this->get_event($id);
+                if ($eventInfo['user'] == api_get_user_id()) {
+                    Database::delete($this->tbl_personal_agenda, array('id = ?' => $id));
+                }
+                break;
+            case 'course':
+                $course_id = api_get_course_int_id();
+                if (!empty($course_id) && api_is_allowed_to_edit(null, true)) {
+                    Database::delete($this->tbl_course_agenda, array('id = ? AND c_id = ?' => array($id, $course_id)));
+                }
+                break;
+            case 'admin':
+                if (api_is_platform_admin()) {
+                    Database::delete($this->tbl_global_agenda, array('id = ?' => $id));
+                }
+                break;
+        }
+    }
+
+    /**
+     *
+     * Get agenda events
+     * @param    int        start tms
+     * @param    int        end tms
+     * @param    int        course id *integer* not the course code
+     * @param   int     user id
+     *
+     */
+    public function get_events($start, $end, $course_id = null, $group_id = null, $user_id = 0)
+    {
+
+        switch ($this->type) {
+            case 'admin':
+                $this->get_platform_events($start, $end);
+                break;
+            case 'course':
+                $session_id  = api_get_session_id();
+                $course_info = api_get_course_info_by_id($course_id);
+                $this->get_course_events($start, $end, $course_info, $group_id, $session_id, $user_id);
+                break;
+            case 'personal':
+            default:
+                //Getting personal events
+                $this->get_personal_events($start, $end);
+
+                //Getting platform/admin events
+                $this->get_platform_events($start, $end);
+
+                //Getting course events
+                $my_course_list = array();
+
+                if (!api_is_anonymous()) {
+                    $session_list   = SessionManager::get_sessions_by_user(api_get_user_id());
+                    $my_course_list = CourseManager::get_courses_list_by_user_id(api_get_user_id(), true);
+                }
+
+                if (!empty($session_list)) {
+                    foreach ($session_list as $session_item) {
+                        $my_courses    = $session_item['courses'];
+                        $my_session_id = $session_item['session_id'];
+                        if (!empty($my_courses)) {
+                            foreach ($my_courses as $course_item) {
+                                $course_info = api_get_course_info_by_id($course_item['id']);
+                                $this->get_course_events($start, $end, $course_info, 0, $my_session_id);
+                            }
+                        }
+                    }
+                }
+
+                if (!empty($my_course_list)) {
+                    foreach ($my_course_list as $course_info_item) {
+                        if (isset($course_id) && !empty($course_id)) {
+                            if ($course_info_item['real_id'] == $course_id) {
+                                $this->get_course_events($start, $end, $course_info_item);
+                            }
+                        } else {
+                            $this->get_course_events($start, $end, $course_info_item);
+                        }
+                    }
+                }
+                break;
+        }
+        if (!empty($this->events)) {
+            return json_encode($this->events);
+        }
+
+        return '';
+    }
+
+    /**
+     * @param int $id
+     * @param int $day_delta
+     * @param int $minute_delta
+     * @return int
+     */
+    public function resize_event($id, $day_delta, $minute_delta)
+    {
+        // we convert the hour delta into minutes and add the minute delta
+        $delta = ($day_delta * 60 * 24) + $minute_delta;
+        $delta = intval($delta);
+
+        $event = $this->get_event($id);
+        if (!empty($event)) {
+            switch ($this->type) {
+                case 'personal':
+                    $sql    = "UPDATE $this->tbl_personal_agenda SET all_day = 0, enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
+							WHERE id=".intval($id);
+                    $result = Database::query($sql);
+                    break;
+                case 'course':
+                    $sql    = "UPDATE $this->tbl_course_agenda SET all_day = 0,  end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
+							WHERE c_id = ".$this->course['real_id']." AND id=".intval($id);
+                    $result = Database::query($sql);
+                    break;
+                case 'admin':
+                    $sql    = "UPDATE $this->tbl_global_agenda SET all_day = 0, end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
+							WHERE id=".intval($id);
+                    $result = Database::query($sql);
+                    break;
+            }
+        }
+
+        return 1;
+
+    }
+
+    /**
+     * @param int $id
+     * @param int $day_delta
+     * @param int $minute_delta
+     * @return int
+     */
+    public function move_event($id, $day_delta, $minute_delta)
+    {
+        // we convert the hour delta into minutes and add the minute delta
+        $delta = ($day_delta * 60 * 24) + $minute_delta;
+        $delta = intval($delta);
+
+        $event = $this->get_event($id);
+
+        $all_day = 0;
+        if ($day_delta == 0 && $minute_delta == 0) {
+            $all_day = 1;
+        }
+
+        if (!empty($event)) {
+            switch ($this->type) {
+                case 'personal':
+                    $sql    = "UPDATE $this->tbl_personal_agenda SET all_day = $all_day, date = DATE_ADD(date, INTERVAL $delta MINUTE), enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
+							WHERE id=".intval($id);
+                    $result = Database::query($sql);
+                    break;
+                case 'course':
+                    $sql    = "UPDATE $this->tbl_course_agenda SET all_day = $all_day, start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE), end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
+							WHERE c_id = ".$this->course['real_id']." AND id=".intval($id);
+                    $result = Database::query($sql);
+                    break;
+                case 'admin':
+                    $sql    = "UPDATE $this->tbl_global_agenda SET all_day = $all_day, start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE), end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
+							WHERE id=".intval($id);
+                    $result = Database::query($sql);
+                    break;
+            }
+        }
+
+        return 1;
+    }
+
+    /**
+     * Gets a single event
+     *
+     * @param int event id
+     * @return array
+     */
+    public function get_event($id)
+    {
+        // make sure events of the personal agenda can only be seen by the user himself
+        $id    = intval($id);
+        $event = null;
+        switch ($this->type) {
+            case 'personal':
+                $sql    = " SELECT * FROM ".$this->tbl_personal_agenda." WHERE id = $id AND user = ".api_get_user_id();
+                $result = Database::query($sql);
+                if (Database::num_rows($result)) {
+                    $event                = Database::fetch_array($result, 'ASSOC');
+                    $event['description'] = $event['text'];
+                    $event['start_date']  = $event['date'];
+                    $event['end_date']    = $event['enddate'];
+                }
+                break;
+            case 'course':
+                if (!empty($this->course['real_id'])) {
+                    $sql    = " SELECT * FROM ".$this->tbl_course_agenda." WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
+                    $result = Database::query($sql);
+                    if (Database::num_rows($result)) {
+                        $event                = Database::fetch_array($result, 'ASSOC');
+                        $event['description'] = $event['content'];
+                    }
+                }
+                break;
+            case 'admin':
+            case 'platform':
+                $sql    = " SELECT * FROM ".$this->tbl_global_agenda." WHERE id=".$id;
+                $result = Database::query($sql);
+                if (Database::num_rows($result)) {
+                    $event                = Database::fetch_array($result, 'ASSOC');
+                    $event['description'] = $event['content'];
+                }
+                break;
+        }
+
+        return $event;
+    }
+
+    /**
+     *
+     * Gets personal events
+     * @param int    start date tms
+     * @param int    end   date tms
+     */
+    public function get_personal_events($start, $end)
+    {
+        $start   = intval($start);
+        $end     = intval($end);
+        $start   = api_get_utc_datetime($start);
+        $end     = api_get_utc_datetime($end);
+        $user_id = api_get_user_id();
+
+        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
+				   WHERE date >= '".$start."' AND (enddate <='".$end."' OR enddate IS NULL) AND user = $user_id";
+
+        $result    = Database::query($sql);
+        $my_events = array();
+        if (Database::num_rows($result)) {
+            while ($row = Database::fetch_array($result, 'ASSOC')) {
+                $event                = array();
+                $event['id']          = 'personal_'.$row['id'];
+                $event['title']       = $row['title'];
+                $event['className']   = 'personal';
+                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
+                $event['editable']    = true;
+
+                $event['sent_to'] = get_lang('Me');
+                $event['type']    = 'personal';
+
+                if (!empty($row['date']) && $row['date'] != '0000-00-00 00:00:00') {
+                    $event['start'] = $this->format_event_date($row['date']);
+                }
+
+                if (!empty($row['enddate']) && $row['enddate'] != '0000-00-00 00:00:00') {
+                    $event['end'] = $this->format_event_date($row['enddate']);
+                }
+                $event['description'] = $row['text'];
+                $event['allDay']      = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
+                $my_events[]          = $event;
+                $this->events[]       = $event;
+            }
+        }
+
+        return $my_events;
+    }
+
+    /**
+     * @param int $start
+     * @param int $end
+     * @param array $course_info
+     * @param int $group_id
+     * @param int $session_id
+     * @param int $user_id
+     * @return array
+     */
+    public function get_course_events($start, $end, $course_info, $group_id = 0, $session_id = 0, $user_id = 0)
+    {
+        $course_id  = $course_info['real_id'];
+        $user_id    = intval($user_id);
+        $group_list = GroupManager::get_group_list(null, $course_info['code']);
+
+        $group_name_list = array();
+        if (!empty($group_list)) {
+            foreach ($group_list as $group) {
+                $group_name_list[$group['id']] = $group['name'];
+            }
+        }
+
+        if (!api_is_allowed_to_edit()) {
+            $group_memberships = GroupManager::get_group_ids($course_id, api_get_user_id());
+            $user_id           = api_get_user_id();
+        } else {
+            $group_memberships = array_keys($group_name_list);
+        }
+
+        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
+        $tbl_property      = Database::get_course_table(TABLE_ITEM_PROPERTY);
+
+
+        if (!empty($group_id)) {
+            $group_memberships = array($group_id);
+        }
+
+        $session_id = intval($session_id);
+
+        if (is_array($group_memberships) && count($group_memberships) > 0) {
+            if (api_is_allowed_to_edit()) {
+                if (!empty($user_id)) {
+                    $where_condition = "( ip.to_user_id = $user_id AND ip.to_group_id is null OR ip.to_group_id IN (0, ".implode(
+                        ", ",
+                        $group_memberships
+                    ).") ) ";
+                } else {
+                    $where_condition = "( ip.to_group_id is null OR ip.to_group_id IN (0, ".implode(
+                        ", ",
+                        $group_memberships
+                    ).") ) ";
+                }
+            } else {
+                $where_condition = "( ip.to_user_id = $user_id OR ip.to_group_id IN (0, ".implode(
+                    ", ",
+                    $group_memberships
+                ).") ) ";
+            }
+
+            $sql = "SELECT DISTINCT
+                    agenda.*,
+                    ip.visibility,
+                    ip.to_group_id,
+                    ip.insert_user_id,
+                    ip.ref,
+                    to_user_id
+                    FROM ".$tlb_course_agenda." agenda, ".$tbl_property." ip
+                    WHERE   agenda.id       = ip.ref  AND
+                            ip.tool         ='".TOOL_CALENDAR_EVENT."' AND
+                            $where_condition AND
+                            ip.visibility   = '1' AND
+                            agenda.c_id     = $course_id AND
+                            ip.c_id         = $course_id
+                    GROUP BY id";
+
+        } else {
+            if (api_is_allowed_to_edit()) {
+                $where_condition = "";
+            } else {
+                $where_condition = "( ip.to_user_id=$user_id OR ip.to_group_id='0') AND ";
+            }
+
+            $sql = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref, to_user_id
+                    FROM ".$tlb_course_agenda." agenda, ".$tbl_property." ip
+                    WHERE   agenda.id = ip.ref AND
+                            ip.tool='".TOOL_CALENDAR_EVENT."' AND
+                            $where_condition
+                            ip.visibility='1' AND
+                            agenda.c_id = $course_id AND
+                            ip.c_id = $course_id AND
+                            agenda.session_id = $session_id AND
+                            ip.id_session = $session_id
+                    ";
+
+        }
+
+        $result = Database::query($sql);
+        $events = array();
+        if (Database::num_rows($result)) {
+            $events_added = array();
+            while ($row = Database::fetch_array($result, 'ASSOC')) {
+                //to gather sent_tos
+                $sql            = "SELECT to_user_id, to_group_id
+                    FROM ".$tbl_property." ip
+                    WHERE   ip.tool         = '".TOOL_CALENDAR_EVENT."' AND
+                            ref             = {$row['ref']} AND
+                            ip.visibility   = '1' AND
+                            ip.c_id         = $course_id";
+                $sent_to_result = Database::query($sql);
+                $user_to_array  = array();
+                $group_to_array = array();
+                while ($row_send_to = Database::fetch_array($sent_to_result, 'ASSOC')) {
+                    if (!empty($row_send_to['to_group_id'])) {
+                        $group_to_array[] = $row_send_to['to_group_id'];
+                    }
+                    if (!empty($row_send_to['to_user_id'])) {
+                        $user_to_array[] = $row_send_to['to_user_id'];
+                    }
+                }
+
+                //Only show events from the session
+                /*if (api_get_course_int_id()) {
+                    if ($row['session_id'] != api_get_session_id()) {
+                        continue;
+                    }
+                }*/
+
+                $event = array();
+
+                $event['id'] = 'course_'.$row['id'];
+
+                //To avoid doubles
+                if (in_array($row['id'], $events_added)) {
+                    continue;
+                }
+
+                $events_added[] = $row['id'];
+
+                $attachment = get_attachment($row['id'], $course_id);
+
+                $has_attachment = '';
+
+                if (!empty($attachment)) {
+                    $has_attachment      = Display::return_icon('attachment.gif', get_lang('Attachment'));
+                    $user_filename       = $attachment['filename'];
+                    $full_file_name      = 'download.php?file='.$attachment['path'].'&course_id='.$course_id;
+                    $event['attachment'] = $has_attachment.Display::url($user_filename, $full_file_name);
+                } else {
+                    $event['attachment'] = '';
+                }
+
+                $event['title']     = $row['title'];
+                $event['className'] = 'course';
+                $event['allDay']    = 'false';
+
+                $event['course_id'] = $course_id;
+
+                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
+                if (isset($row['session_id']) && !empty($row['session_id'])) {
+                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
+                }
+
+                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
+                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
+                }
+
+                $event['editable'] = false;
+
+                if (api_is_allowed_to_edit() && $this->type == 'course') {
+                    $event['editable'] = true;
+                }
+
+                if (!empty($row['start_date']) && $row['start_date'] != '0000-00-00 00:00:00') {
+                    $event['start'] = $this->format_event_date($row['start_date']);
+                }
+                if (!empty($row['end_date']) && $row['end_date'] != '0000-00-00 00:00:00') {
+                    $event['end'] = $this->format_event_date($row['end_date']);
+                }
+
+                $event['sent_to'] = '';
+                //$event['type']    = $this->type;
+                $event['type'] = 'course';
+                if ($row['session_id'] != 0) {
+                    $event['type'] = 'session';
+                }
+
+                //Event Sent to a group?
+                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
+                    $sent_to = array();
+                    if (!empty($group_to_array)) {
+                        foreach ($group_to_array as $group_item) {
+                            $sent_to[] = $group_name_list[$group_item];
+                        }
+                    }
+                    $sent_to          = implode('@@', $sent_to);
+                    $sent_to          = str_replace('@@', '</div><div class="label_tag notice">', $sent_to);
+                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
+                    $event['type']    = 'group';
+                }
+
+                //Event sent to a user?
+                if (isset($row['to_user_id'])) {
+                    $sent_to = array();
+                    if (!empty($user_to_array)) {
+                        foreach ($user_to_array as $item) {
+                            $user_info = api_get_user_info($item);
+                            // add username as tooltip for $event['sent_to'] - ref #4226
+                            $username  = api_htmlentities(
+                                sprintf(get_lang('LoginX'), $user_info['username']),
+                                ENT_QUOTES
+                            );
+                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
+                        }
+                    }
+                    $sent_to          = implode('@@', $sent_to);
+                    $sent_to          = str_replace('@@', '</div><div class="label_tag notice">', $sent_to);
+                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
+                }
+
+                //Event sent to everyone!
+                if (empty($event['sent_to'])) {
+                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
+                }
+
+                $event['description'] = $row['content'];
+                $event['allDay']      = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
+
+                $this->events[] = $event;
+            }
+        }
+
+        return $this->events;
+    }
+
+    /**
+     * @param int $start
+     * @param int $end
+     * @return array
+     */
+    public function get_platform_events($start, $end)
+    {
+        $start = intval($start);
+        $end   = intval($end);
+
+        $start = api_get_utc_datetime($start);
+        $end   = api_get_utc_datetime($end);
+
+        $access_url_id = api_get_current_access_url_id();
+
+        $sql = "SELECT * FROM ".$this->tbl_global_agenda."
+				   WHERE start_date >= '".$start."' AND end_date <= '".$end."' AND access_url_id = $access_url_id ";
+
+        $result    = Database::query($sql);
+        $my_events = array();
+        if (Database::num_rows($result)) {
+            while ($row = Database::fetch_array($result, 'ASSOC')) {
+                $event                = array();
+                $event['id']          = 'platform_'.$row['id'];
+                $event['title']       = $row['title'];
+                $event['className']   = 'platform';
+                $event['allDay']      = 'false';
+                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
+                $event['editable']    = false;
+
+                $event['type'] = 'admin';
+
+                if (api_is_platform_admin() && $this->type == 'admin') {
+                    $event['editable'] = true;
+                }
+
+                if (!empty($row['start_date']) && $row['start_date'] != '0000-00-00 00:00:00') {
+                    $event['start'] = $this->format_event_date($row['start_date']);
+                }
+                if (!empty($row['end_date']) && $row['end_date'] != '0000-00-00 00:00:00') {
+                    $event['end'] = $this->format_event_date($row['end_date']);
+                }
+
+                $event['description'] = $row['content'];
+                $event['allDay']      = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
+
+                $my_events[]    = $event;
+                $this->events[] = $event;
+            }
+        }
+
+        return $my_events;
+    }
+
+    /**
+     * Format needed for the Fullcalendar js lib
+     * @param string UTC time
+     * @return string
+     */
+    public function format_event_date($utc_time)
+    {
+        return date('c', api_strtotime(api_get_local_time($utc_time)));
+    }
+
+    /**
+     * this function shows the form with the user that were not selected
+     * @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+     * @return string html code
+     */
+    static function construct_not_selected_select_form(
+        $group_list = null,
+        $user_list = null,
+        $to_already_selected = array()
+    ) {
+        $html = '<select id="users_to_send_id" data-placeholder="'.get_lang(
+            'Select'
+        ).'" name="users_to_send[]" multiple="multiple" style="width:250px" class="chzn-select">';
+
+        if ($to_already_selected == 'everyone') {
+            $html .= '<option value="everyone" checked="checked">'.get_lang('Everyone').'</option>';
+        } else {
+            $html .= '<option value="everyone">'.get_lang('Everyone').'</option>';
+        }
+
+        if (is_array($group_list)) {
+            $html .= '<optgroup label="'.get_lang('Groups').'">';
+            foreach ($group_list as $this_group) {
+                if (!is_array($to_already_selected) || !in_array("GROUP:".$this_group['id'], $to_already_selected)) {
+                    // $to_already_selected is the array containing the groups (and users) that are already selected
+                    $count_users = isset($this_group['count_users']) ? $this_group['count_users'] : $this_group['userNb'];
+                    $count_users = " &ndash; $count_users ".get_lang('Users');
+
+                    $html .= '<option value="GROUP:'.$this_group['id'].'"> '.$this_group['name'].$count_users.'</option>';
+                }
+            }
+            $html .= '</optgroup>';
+        }
+
+        // adding the individual users to the select form
+        if (is_array($group_list)) {
+            $html .= '<optgroup label="'.get_lang('Users').'">';
+        }
+        foreach ($user_list as $this_user) {
+            // $to_already_selected is the array containing the users (and groups) that are already selected
+            if (!is_array($to_already_selected) || !in_array("USER:".$this_user['user_id'], $to_already_selected)) {
+                $username = api_htmlentities(sprintf(get_lang('LoginX'), $this_user['username']), ENT_QUOTES);
+                // @todo : add title attribute $username in the jqdialog window. wait for a chosen version to inherit title attribute
+                $html .= '<option title="'.$username.'" value="USER:'.$this_user['user_id'].'">'.api_get_person_name(
+                    $this_user['firstname'],
+                    $this_user['lastname']
+                ).' ('.$this_user['username'].') </option>';
+            }
+        }
+        if (is_array($group_list)) {
+            $html .= '</optgroup>';
+            $html .= "</select>";
+        }
+
+        return $html;
+    }
+
+    static function construct_not_selected_select_form_validator(
+        $form,
+        $group_list = null,
+        $user_list = null,
+        $to_already_selected = array()
+    ) {
+
+        $params = array(
+            'id'               => 'users_to_send_id',
+            'data-placeholder' => get_lang('Select'),
+            'multiple'         => 'multiple',
+            'style'            => 'width:250px',
+            'class'            => 'chzn-select'
+        );
+
+        $select = $form->addElement('select', 'users_to_send', get_lang('To'), null, $params);
+
+        $select->addOption(get_lang('Everyone'), 'everyone');
+
+        $options = array();
+        if (is_array($group_list)) {
+            foreach ($group_list as $this_group) {
+                if (!is_array($to_already_selected) || !in_array("GROUP:".$this_group['id'], $to_already_selected)) {
+                    // $to_already_selected is the array containing the groups (and users) that are already selected
+                    $count_users = isset($this_group['count_users']) ? $this_group['count_users'] : $this_group['userNb'];
+                    $count_users = " &ndash; $count_users ".get_lang('Users');
+                    $options[]   = array(
+                        'text'  => $this_group['name'].$count_users,
+                        'value' => "GROUP:".$this_group['id']
+                    );
+                }
+            }
+            $select->addOptGroup($options, get_lang('Groups'));
+        }
+
+        // adding the individual users to the select form
+        if (is_array($group_list)) {
+            $options = array();
+            foreach ($user_list as $this_user) {
+                // $to_already_selected is the array containing the users (and groups) that are already selected
+                if (!is_array($to_already_selected) || !in_array("USER:".$this_user['user_id'], $to_already_selected)) {
+                    //$username = api_htmlentities(sprintf(get_lang('LoginX'), $this_user['username']), ENT_QUOTES);
+                    // @todo : add title attribute $username in the jqdialog window. wait for a chosen version to inherit title attribute
+                    // from <option> to <li>
+                    //$html .= '<option title="'.$username.'" value="USER:'.$this_user['user_id'].'">'.api_get_person_name($this_user['firstname'], $this_user['lastname']).' ('.$this_user['username'].') </option>';
+                    $options[] = array(
+                        'text'  => api_get_person_name(
+                            $this_user['firstname'],
+                            $this_user['lastname']
+                        ).' ('.$this_user['username'].')',
+                        'value' => "USER:".$this_user['user_id']
+                    );
+                }
+            }
+            $select->addOptGroup($options, get_lang('Users'));
+        }
+    }
+
+    /**
+     * This public function separates the users from the groups
+     * users have a value USER:XXX (with XXX the dokeos id
+     * groups have a value GROUP:YYY (with YYY the group id)
+     * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+     * @param array
+     * @return array
+     */
+    public function separate_users_groups($to)
+    {
+        $grouplist = array();
+        $userlist  = array();
+        $send_to   = null;
+
+        $send_to['everyone'] = false;
+        if (is_array($to) && count($to) > 0) {
+            foreach ($to as $to_item) {
+                if ($to_item == 'everyone') {
+                    $send_to['everyone'] = true;
+                } else {
+                    list($type, $id) = explode(':', $to_item);
+                    switch ($type) {
+                        case 'GROUP':
+                            $grouplist[] = $id;
+                            break;
+                        case 'USER':
+                            $userlist[] = $id;
+                            break;
+                    }
+                }
+            }
+            $send_to['groups'] = $grouplist;
+            $send_to['users']  = $userlist;
+
+        }
+
+        return $send_to;
+    }
+
+    /**
+     * @param array $params
+     */
+    static function show_form($params = array())
+    {
+        $form = new FormValidator('add_event', 'POST', api_get_self().'?'.api_get_cidreq(), null, array('enctype' => 'multipart/form-data'));
+        $id   = isset($params['id']) ? $params['id'] : null;
+
+        if ($id) {
+            $form_title = get_lang('ModifyCalendarItem');
+            $button     = get_lang('ModifyEvent');
+        } else {
+            $form_title = get_lang('AddCalendarItem');
+            $button     = get_lang('AgendaAdd');
+        }
+
+        $form->addElement('header', $form_title);
+        $form->addElement('hidden', 'id', $id);
+        $form->addElement('hidden', 'action', $params['action']);
+        $form->addElement('hidden', 'id_attach', $params['id_attach']);
+
+        $form->addElement('text', 'title', get_lang('ItemTitle'));
+
+        $group_id = api_get_group_id();
+
+        if (isset ($group_id) && !empty($group_id)) {
+            $form->addElement('hidden', 'selected_form[0]', "GROUP:'.$group_id.'");
+            $form->addElement('hidden', 'to', 'true');
+        } else {
+            self::show_to_form($form, $to);
+        }
+
+        $form->addElement('text', 'start_date', get_lang('StartDate'));
+        $form->addElement('text', 'end_date', get_lang('EndDate'));
+
+        if (empty($id)) {
+            $form->addElement(
+                'advanced_settings',
+                '<a href="javascript://" onclick="return plus_repeated_event();"><span id="plus2">
+                                                  <img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang(
+                    'RepeatEvent'
+                ).'</span>
+                                </a>'
+            );
+            $form->addElement('html', '<div style="display:block">');
+
+            $form->addElement('checkbox', 'repeat', null, get_lang('RepeatEvent'));
+
+            $repeat_events = array(
+                'daily'         => get_lang('RepeatDaily'),
+                'weekly'        => get_lang('RepeatWeekly'),
+                'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
+                'yearly'        => get_lang('RepeatYearly')
+            );
+
+            $form->addElement('select', 'repeat_type', get_lang('RepeatType'), $repeat_events);
+            $form->addElement('text', 'repeat_end_day', get_lang('RepeatEnd'));
+            $form->addElement('html', '</div>');
+
+            if (!api_is_allowed_to_edit(null, true)) {
+                $toolbar = 'AgendaStudent';
+            } else {
+                $toolbar = 'Agenda';
+            }
+            //$form->addElement('html_editor', 'content', get_lang('Description'), null, array('ToolbarSet' => $toolbar, 'Width' => '100%', 'Height' => '200'));
+
+            $form->addElement('file', 'user_upload', get_lang('AddAnAttachment'));
+            $form->addElement('text', 'file_comment', get_lang('Comment'));
+        }
+
+        $form->addElement('button', 'submit', $button);
+        $form->display();
+    }
+
+    /**
+     * @param array $form
+     * @param $to_already_selected
+     */
+    public static function show_to_form($form, $to_already_selected)
+    {
+        $order = 'lastname';
+        if (api_is_western_name_order()) {
+            $order = 'firstname';
+        }
+        $user_list  = CourseManager::get_user_list_from_course_code(
+            api_get_course_id(),
+            api_get_session_id(),
+            null,
+            $order
+        );
+        $group_list = CourseManager::get_group_list_of_course(api_get_course_id(), api_get_session_id());
+
+        self::construct_not_selected_select_form_validator($form, $group_list, $user_list, $to_already_selected);
+    }
+}

+ 6 - 0
main/template/default/admin/administrator/role/add.tpl

@@ -0,0 +1,6 @@
+{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
+{% block content %}
+    <form action="{{ path('admin_administrator_roles_add')}}" method="post" {{ form_enctype(form) }}>
+        {{ form_widget(form) }}
+    </form>
+{% endblock %}

+ 6 - 0
main/template/default/admin/administrator/role/edit.tpl

@@ -0,0 +1,6 @@
+{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
+{% block content %}
+    <form action="{{ path('admin_administrator_roles_edit')}}" method="post" {{ form_enctype(form) }}>
+        {{ form_widget(form) }}
+    </form>
+{% endblock %}

+ 8 - 0
main/template/default/admin/administrator/role/list.tpl

@@ -0,0 +1,8 @@
+{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
+{% block content %}
+    {% for item in items %}
+         {{ item.name }} - {{ item.role}}  <a class="btn" href="{{ url('admin_administrator_roles_edit', { id: item.id }) }}"> Edit</a>
+        <br />
+    {% endfor %}
+
+{% endblock %}

+ 6 - 0
main/template/default/auth/login.tpl

@@ -0,0 +1,6 @@
+<form action="{{ path('check-login') }}" method="post">
+    {{ error }}
+    <input type="text" name="username"  />
+    <input type="password" name="password" value="" />
+    <input type="submit" />
+</form>

+ 143 - 0
src/ChamiloLMS/Command/Translation/ExportLanguagesCommand.php

@@ -0,0 +1,143 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace ChamiloLMS\Command\Translation;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Finder\Finder;
+
+/**
+ * Class ExportLanguagesCommand
+ * @package ChamiloLMS\Command\Translation
+ */
+class ExportLanguagesCommand extends Command
+{
+    /**
+     *
+     */
+    protected function configure()
+    {
+        $this
+            ->setName('translation:export_to_gettext')
+            ->setDescription('Export chamilo translations to po files');
+            //->addArgument('theme', InputArgument::OPTIONAL, 'The theme to dump, if none is set then all themes will be generated', null);
+    }
+
+    /**
+     * @param Console\Input\InputInterface $input
+     * @param Console\Output\OutputInterface $output
+     * @return int|null|void
+     */
+    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
+    {
+        $languageList = array('english', 'spanish', 'french');
+        //$languageList = array('spanish');
+        foreach ($languageList as $lang) {
+            $output->writeln("<info>Generating lang po files for: $lang</info>");
+            $this->convertLanguageToGettext($lang, $output);
+        }
+    }
+
+    /**
+     * @param string $destinationLanguage chamilo language 'spanish', 'french', etc
+     * @param $output
+     */
+    private function convertLanguageToGettext($destinationLanguage, Console\Output\OutputInterface $output)
+    {
+        /** @var \Silex\Application $app */
+        $app = $this->getApplication()->getSilexApplication();
+        $tempPath = $app['paths']['sys_temp_path'].'langs';
+
+        if (!is_dir($tempPath)) {
+            mkdir($tempPath);
+            $output->writeln('<info>folder $tempPath created </info>');
+        }
+
+        $isocode = api_get_language_isocode($destinationLanguage);
+
+        $englishPath = $app['paths']['root_sys'].'main/lang/english/';
+
+        // Translate this language.
+        $toLanguagePath = $app['paths']['root_sys'].'main/lang/'.$destinationLanguage;
+
+        if (is_dir($englishPath)) {
+            if ($dh = opendir($englishPath)) {
+                while (($file = readdir($dh)) !== false) {
+                    $info = pathinfo($file);
+                    if ($info['extension'] != 'php') {
+                        continue;
+                    }
+                    $info['filename'] = explode('.', $info['filename']);
+                    $info['filename'] = $info['filename'][0];
+
+                    if ($info['filename'] != 'admin') {
+                        //continue;
+                    }
+
+                    $translations = array();
+                    $filename = $englishPath.'/'.$file;
+                    $po = file($filename);
+                    if (!file_exists($filename) || !file_exists($toLanguagePath.'/'.$file)) {
+                        continue;
+                    }
+
+                    foreach ($po as $line) {
+                        $pos = strpos($line, '=');
+                        if ($pos) {
+                            $variable = (substr($line, 1, $pos-1));
+                            $variable = trim($variable);
+
+                            require $filename;
+                            $my_variable_in_english = $$variable;
+                            require $toLanguagePath.'/'.$file;
+                            $my_variable = $$variable;
+                            /** This fixes a notice due an array in the lang files */
+                            if (strpos($variable, 'langNameOfLang') === false) {
+
+                                $translations[] = array(
+                                    'msgid'  => $variable,
+                                    'msgstr' => $my_variable
+                                );
+                            } else {
+                                continue;
+                            }
+                        }
+                    }
+
+                    //var_dump($translations);
+
+
+                    if (!is_dir($tempPath.'/'.$info['filename'])) {
+                        mkdir($tempPath.'/'.$info['filename']);
+                        $output->writeln('<info>folder '.$tempPath.'/'.$info['filename'].' created </info>');
+                    }
+
+                    $new_po_file = $tempPath.'/'.$info['filename'].'/'.$isocode.'.po';
+                    $fp = fopen($new_po_file, 'w');
+                    $header = 'msgid ""'."\n".'msgstr ""'."\n".'"Content-Type: text/plain; charset=utf-8 \n"';
+                    fwrite($fp, $header);
+                    fwrite($fp, "\n\n");
+                    foreach ($translations as $item) {
+                        $line = 'msgid "'.addslashes($item['msgid']).'"'."\n";
+
+                        $translated = $item['msgstr'];
+                        $translated = addslashes($translated);
+                        $translated = str_replace(array("\\'"), "'", $translated);
+                        $line .= 'msgstr "'.$translated.'"'."\n\n";
+                        fwrite($fp, $line);
+                    }
+                    fclose($fp);
+
+                    $message = "File $file converted to ".$new_po_file;
+                    $output->writeln($message);
+
+                }
+                closedir($dh);
+            }
+        }
+    }
+}

+ 109 - 0
src/ChamiloLMS/Controller/Admin/Administrator/RoleController.php

@@ -0,0 +1,109 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace ChamiloLMS\Controller\Admin\Administrator;
+
+use ChamiloLMS\Controller\BaseController;
+use Silex\Application;
+use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+use Entity;
+use ChamiloLMS\Form\RoleType;
+
+/**
+ * Class RoleController
+ * @todo @route and @method function don't work yet
+ * @package ChamiloLMS\Controller
+ * @author Julio Montoya <gugli100@gmail.com>
+ */
+class RoleController extends BaseController
+{
+    /**
+     *
+     * @param Application $app
+     * @Route("/")
+     * @Method({"GET"})
+     */
+    public function indexAction()
+    {
+        $items = parent::listAction('array');
+        $template = $this->get('template');
+        $template->assign('items', $items);
+        $response = $template->render_template('admin/administrator/role/list.tpl');
+        return new Response($response, 200, array());
+    }
+
+    /**
+     *
+     * @Route("/{id}", requirements={"id" = "\d+"}, defaults={"foo" = "bar"})
+     * @Method({"GET"})
+     */
+    public function readAction($id)
+    {
+        return parent::readAction($id);
+    }
+
+    public function editAction($id)
+    {
+        $roleRepo = $this->getRepository();
+        $role = $roleRepo->findOneById($id);
+        $form = $this->get('form.factory')->create(new RoleType(), $role);
+
+        $template = $this->get('template');
+        $template->assign('form', $form->createView());
+        $response = $template->render_template('admin/administrator/role/edit.tpl');
+        return new Response($response, 200, array());
+    }
+
+    public function addAction()
+    {
+        $form = $this->get('form.factory')->create(new RoleType());
+
+        $form->bind($this->getRequest());
+
+        if ($form->isValid()) {
+            $em = $this->get('orm.em');
+            $role = $form->getData();
+            $em->persist($role);
+            $em->flush();
+
+            $params = array('id' => $role->getId());
+            $url = $this->get('url_generator')->generate('admin_administrator_roles_read', $params);
+            return $this->redirect($url);
+        }
+
+        $template = $this->get('template');
+        $template->assign('form', $form->createView());
+        $response = $template->render_template('admin/administrator/role/add.tpl');
+        return new Response($response, 200, array());
+    }
+
+    /**
+     * @Route("", name="api_events_create")
+     * @Method({"POST"})
+     */
+    public function createAction()
+    {
+        return parent::createAction();
+    }
+
+    /**
+     * @see BaseController::getRepository()
+     * @return EntityRepository
+     */
+    protected function getRepository()
+    {
+        return $this->get('orm.em')->getRepository('Entity\Role');
+    }
+
+    /**
+     * @see BaseController::getNewEntity()
+     * @return Object
+     */
+    protected function getNewEntity()
+    {
+        return new Entity\Role();
+    }
+}

+ 294 - 0
src/ChamiloLMS/Controller/BaseController.php

@@ -0,0 +1,294 @@
+<?php
+
+/* For licensing terms, see /license.txt */
+namespace ChamiloLMS\Controller;
+
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Doctrine\ORM\Query;
+use Doctrine\ORM\NoResultException;
+use Silex\Application;
+
+/**
+ * Each entity controller must extends this class.
+ *
+ * @abstract
+ */
+abstract class BaseController
+{
+    protected $app;
+
+    /**
+     * @param $app
+     */
+    public function __construct($app)
+    {
+        $this->app = $app;
+    }
+
+    public function getRequest()
+    {
+        return $this->get('request');
+    }
+
+    public function redirect($redirect)
+    {
+        return $this->app->redirect($redirect);
+    }
+
+    /**
+     * @param string $item
+     * @return mixed
+     */
+    public function get($item)
+    {
+        return $this->app[$item];
+    }
+
+    /**
+     * This method should return the entity's repository.
+     *
+     * @abstract
+     * @return EntityRepository
+     */
+    abstract protected function getRepository();
+
+    /**
+     * This method should return a new entity instance to be used for the "create" action.
+     *
+     * @abstract
+     * @return Object
+     */
+    abstract protected function getNewEntity();
+
+    /**
+     * Base "list" action.
+     *
+     * @return JsonResponse
+     */
+    protected function listAction($format = 'json')
+    {
+        return $this->getList($format);
+    }
+
+    protected function getList($format = 'json')
+    {
+        $list = $this->getRepository()
+            ->createQueryBuilder('e')
+            ->getQuery()->getResult(Query::HYDRATE_ARRAY);
+
+        switch ($format) {
+            case 'json':
+                return new JsonResponse($list);
+                break;
+            default:
+                return $list;
+                break;
+        }
+
+    }
+
+    /**
+     * Base "read" action.
+     *
+     * @param int $id
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function readAction($id)
+    {
+        $entityInstance = $this->getEntityForJson($id);
+        if (false === $entityInstance) {
+            return $this->createNotFoundException();
+        }
+
+        return new JsonResponse($entityInstance);
+    }
+
+    /**
+     * Base "create" action.
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function createAction()
+    {
+        $json = $this->getDataFromRequest();
+
+
+        $object = $this->updateEntity($this->getNewEntity(), $json);
+
+        if (false === $object) {
+            throw new \Exception('Unable to create the entity');
+        }
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($object);
+        $em->flush();
+
+        return new JsonResponse($this->getEntityForJson($object->getId()));
+    }
+
+    /**
+     * Base "create" action.
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function createJsonAction()
+    {
+        $json = $this->getDataFromRequest();
+
+        if (false === $json) {
+            throw new \Exception('Invalid JSON');
+        }
+
+        $object = $this->updateEntity($this->getNewEntity(), $json);
+
+        if (false === $object) {
+            throw new \Exception('Unable to create the entity');
+        }
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($object);
+        $em->flush();
+
+        return new JsonResponse($this->getEntityForJson($object->getId()));
+    }
+
+    /**
+     * Base "upload" action.
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function updateAction($id)
+    {
+        $object = $this->getEntity($id);
+        if (false === $object) {
+            return $this->createNotFoundException();
+        }
+        $json = $this->getDataFromRequest();
+        if (false === $json) {
+            throw new \Exception('Invalid JSON');
+        }
+        if (false === $this->updateEntity($object, $json)) {
+            throw new \Exception('Unable to update the entity');
+        }
+        $this->getDoctrine()->getManager()->flush($object);
+
+        return new JsonResponse($this->getEntityForJson($object->getId()));
+    }
+
+    /**
+     * Base "upload" action.
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function updateJsonAction($id)
+    {
+        $object = $this->getEntity($id);
+        if (false === $object) {
+            return $this->createNotFoundException();
+        }
+        $json = $this->getDataFromRequest();
+        if (false === $json) {
+            throw new \Exception('Invalid JSON');
+        }
+        if (false === $this->updateEntity($object, $json)) {
+            throw new \Exception('Unable to update the entity');
+        }
+        $this->getDoctrine()->getManager()->flush($object);
+
+        return new JsonResponse($this->getEntityForJson($object->getId()));
+    }
+
+    /**
+     * Base "delete" action.
+     *
+     * @return JsonResponse|NotFoundHttpException
+     */
+    protected function deleteAction($id)
+    {
+        $object = $this->getEntity($id);
+        if (false === $object) {
+            return $this->createNotFoundException();
+        }
+        $em = $this->getDoctrine()->getManager();
+        $em->remove($object);
+        $em->flush();
+
+        return new JsonResponse(array());
+    }
+
+    /**
+     * Returns an entity from its ID, or FALSE in case of error.
+     *
+     * @param int $id
+     * @return Object|boolean
+     */
+    protected function getEntity($id)
+    {
+        try {
+            return $this->getRepository()->find($id);
+        } catch (NoResultException $ex) {
+            return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns an entity from its ID as an associative array, or FALSE in case of error.
+     *
+     * @param int $id
+     * @return array|boolean
+     */
+    protected function getEntityForJson($id)
+    {
+        try {
+            return $this->getRepository()->createQueryBuilder('e')
+                ->where('e.id = :id')
+                ->setParameter('id', $id)
+                ->getQuery()->getSingleResult(Query::HYDRATE_ARRAY);
+        } catch (NoResultException $ex) {
+            return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the request's JSON content, or FALSE in case of error.
+     *
+     * @return string|boolean
+     */
+    protected function getDataFromRequest()
+    {
+        $data = $this->get("request")->getContent();
+        if (!$data) {
+            return false;
+        }
+
+        return $data;
+    }
+
+    /**
+     * Updates an entity with data from a JSON string.
+     * Returns the entity, or FALSE in case of error.
+     *
+     * @param Object $entity
+     * @param string $json
+     * @return Object|boolean
+     */
+    protected function updateEntity($entity, $json)
+    {
+        $data = json_decode($json);
+        if ($data == null) {
+            return false;
+        }
+        foreach ($data as $name => $value) {
+            if ($name != 'id') {
+                $setter = 'set'.ucfirst($name);
+                if (method_exists($entity, $setter)) {
+                    call_user_func_array(array($entity, $setter), array($value));
+                }
+            }
+        }
+
+        return $entity;
+    }
+}

+ 32 - 0
src/ChamiloLMS/Form/RoleType.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace ChamiloLMS\Form;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+use Entity;
+
+class RoleType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        //$role = new Entity\Role();
+
+        $builder->add('name', 'text');
+        $builder->add('role', 'text');
+        $builder->add('submit', 'submit');
+    }
+
+    public function setDefaultOptions(OptionsResolverInterface $resolver)
+    {
+        $resolver->setDefaults(array(
+            'data_class' => 'Entity\Role'
+        ));
+    }
+
+    public function getName()
+    {
+        return 'role';
+    }
+}

+ 71 - 0
src/ChamiloLMS/Provider/ReflectionControllerProvider.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace ChamiloLMS\Provider;
+
+use Silex\Application;
+use Silex\ControllerProviderInterface;
+use Symfony\Component\Routing\Loader\AnnotationFileLoader;
+use Symfony\Component\Routing\Loader\AnnotationClassLoader;
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\Routing\Annotation\Route;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+
+use Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader;
+
+use Doctrine\Common\Annotations\AnnotationReader;
+
+class ReflectionControllerProvider implements ControllerProviderInterface
+{
+    private $controllerName;
+
+    function __construct($controllerName)
+    {
+        $this->controllerName = $controllerName;
+    }
+
+    function connect(Application $app)
+    {
+        /** @var \Silex\ControllerCollection $controllers */
+        $controllers = $app['controllers_factory'];
+
+        //$reflection = new \ReflectionClass($this->class);
+        $reflection = new \ReflectionClass($app[$this->controllerName]);
+
+        $annotationReader = new AnnotationReader();
+        //$classAnnotations = $annotationReader->getClassAnnotations($reflection);
+        $routeAnnotation = new Route(array());
+        $methodAnnotation = new Method(array());
+        $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
+
+        foreach ($methods as $method) {
+            $methodName = $method->getName();
+            if (in_array($methodName, array('__construct'))) {
+                continue;
+            }
+
+            /** @var Route $routeObject */
+            $routeObject = $annotationReader->getMethodAnnotation($method, $routeAnnotation);
+
+            /** @var Method $routeObject */
+            $methodObject = $annotationReader->getMethodAnnotation($method, $methodAnnotation);
+
+            $methodsToString = 'GET';
+            if ($methodObject) {
+                $methodsToString = implode('|', $methodObject->getMethods());
+            }
+
+            $controllers->match($routeObject->getPath(), $this->controllerName.':'.$methodName, $methodsToString);
+        }
+
+        return $controllers;
+    }
+
+    private function adjustPath($path)
+    {
+        $path = lcfirst($path);
+        $path = ('index' === $path) ? '' : $path;
+        $path = '/'.$path;
+
+        return $path;
+    }
+}

+ 153 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/ApplicationDescription.php

@@ -0,0 +1,153 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+class ApplicationDescription
+{
+    const GLOBAL_NAMESPACE = '_global';
+
+    /**
+     * @var Application
+     */
+    private $application;
+
+    /**
+     * @var null|string
+     */
+    private $namespace;
+
+    /**
+     * @var array
+     */
+    private $namespaces;
+
+    /**
+     * @var Command[]
+     */
+    private $commands;
+
+    /**
+     * @var Command[]
+     */
+    private $aliases;
+
+    /**
+     * Constructor.
+     *
+     * @param Application $application
+     * @param string|null $namespace
+     */
+    public function __construct(Application $application, $namespace = null)
+    {
+        $this->application = $application;
+        $this->namespace = $namespace;
+    }
+
+    /**
+     * @return array
+     */
+    public function getNamespaces()
+    {
+        if (null === $this->namespaces) {
+            $this->inspectApplication();
+        }
+
+        return $this->namespaces;
+    }
+
+    /**
+     * @return Command[]
+     */
+    public function getCommands()
+    {
+        if (null === $this->commands) {
+            $this->inspectApplication();
+        }
+
+        return $this->commands;
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return Command
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function getCommand($name)
+    {
+        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
+            throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name));
+        }
+
+        return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
+    }
+
+    private function inspectApplication()
+    {
+        $this->commands = array();
+        $this->namespaces = array();
+
+        $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
+        foreach ($this->sortCommands($all) as $namespace => $commands) {
+            $names = array();
+
+            /** @var Command $command */
+            foreach ($commands as $name => $command) {
+                if (!$command->getName()) {
+                    continue;
+                }
+
+                if ($command->getName() === $name) {
+                    $this->commands[$name] = $command;
+                } else {
+                    $this->aliases[$name] = $command;
+                }
+
+                $names[] = $name;
+            }
+
+            $this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
+        }
+    }
+
+    /**
+     * @param array $commands
+     *
+     * @return array
+     */
+    private function sortCommands(array $commands)
+    {
+        $namespacedCommands = array();
+        foreach ($commands as $name => $command) {
+            $key = $this->application->extractNamespace($name, 1);
+            if (!$key) {
+                $key = '_global';
+            }
+
+            $namespacedCommands[$key][$name] = $command;
+        }
+        ksort($namespacedCommands);
+
+        foreach ($namespacedCommands as &$commands) {
+            ksort($commands);
+        }
+
+        return $namespacedCommands;
+    }
+}

+ 92 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/Descriptor.php

@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+abstract class Descriptor implements DescriptorInterface
+{
+    public function describe($object, array $options = array())
+    {
+        switch (true) {
+            case $object instanceof InputArgument:
+                return $this->describeInputArgument($object, $options);
+            case $object instanceof InputOption:
+                return $this->describeInputOption($object, $options);
+            case $object instanceof InputDefinition:
+                return $this->describeInputDefinition($object, $options);
+            case $object instanceof Command:
+                return $this->describeCommand($object, $options);
+            case $object instanceof Application:
+                return $this->describeApplication($object, $options);
+        }
+
+        throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
+    }
+
+    /**
+     * Describes an InputArgument instance.
+     *
+     * @param InputArgument $argument
+     * @param array         $options
+     *
+     * @return string|mixed
+     */
+    abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
+
+    /**
+     * Describes an InputOption instance.
+     *
+     * @param InputOption $option
+     * @param array       $options
+     *
+     * @return string|mixed
+     */
+    abstract protected function describeInputOption(InputOption $option, array $options = array());
+
+    /**
+     * Describes an InputDefinition instance.
+     *
+     * @param InputDefinition $definition
+     * @param array           $options
+     *
+     * @return string|mixed
+     */
+    abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
+
+    /**
+     * Describes a Command instance.
+     *
+     * @param Command $command
+     * @param array   $options
+     *
+     * @return string|mixed
+     */
+    abstract protected function describeCommand(Command $command, array $options = array());
+
+    /**
+     * Describes an Application instance.
+     *
+     * @param Application $application
+     * @param array       $options
+     *
+     * @return string|mixed
+     */
+    abstract protected function describeApplication(Application $application, array $options = array());
+}

+ 30 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/DescriptorInterface.php

@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+/**
+ * Descriptor interface.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+interface DescriptorInterface
+{
+    /**
+     * Describes an InputArgument instance.
+     *
+     * @param object $object
+     * @param array  $options
+     *
+     * @return string|mixed
+     */
+    public function describe($object, array $options = array());
+}

+ 129 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/JsonDescriptor.php

@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * JSON descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class JsonDescriptor extends Descriptor
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputArgument(InputArgument $argument, array $options = array())
+    {
+        return $this->output(array(
+            'name'        => $argument->getName(),
+            'is_required' => $argument->isRequired(),
+            'is_array'    => $argument->isArray(),
+            'description' => $argument->getDescription(),
+            'default'     => $argument->getDefault(),
+        ), $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputOption(InputOption $option, array $options = array())
+    {
+        return $this->output(array(
+            'name'              => '--'.$option->getName(),
+            'shortcut'          => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
+            'accept_value'      => $option->acceptValue(),
+            'is_value_required' => $option->isValueRequired(),
+            'is_multiple'       => $option->isArray(),
+            'description'       => $option->getDescription(),
+            'default'           => $option->getDefault(),
+        ), $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+    {
+        $inputArguments = array();
+        foreach ($definition->getArguments() as $name => $argument) {
+            $inputArguments[$name] = $this->describeInputArgument($argument, array('as_array' => true));
+        }
+
+        $inputOptions = array();
+        foreach ($definition->getOptions() as $name => $option) {
+            $inputOptions[$name] = $this->describeInputOption($option, array('as_array' => true));
+        }
+
+        return $this->output(array('arguments' => $inputArguments, 'options' => $inputOptions), $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeCommand(Command $command, array $options = array())
+    {
+        $command->getSynopsis();
+        $command->mergeApplicationDefinition(false);
+
+        return $this->output(array(
+            'name'        => $command->getName(),
+            'usage'       => $command->getSynopsis(),
+            'description' => $command->getDescription(),
+            'help'        => $command->getProcessedHelp(),
+            'aliases'     => $command->getAliases(),
+            'definition'  => $this->describeInputDefinition($command->getNativeDefinition(), array('as_array' => true)),
+        ), $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeApplication(Application $application, array $options = array())
+    {
+        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+        $description = new ApplicationDescription($application, $describedNamespace);
+        $commands = array();
+
+        foreach ($description->getCommands() as $command) {
+            $commands[] = $this->describeCommand($command, array('as_array' => true));
+        }
+
+        $data = $describedNamespace
+            ? array('commands' => $commands, 'namespace' => $describedNamespace)
+            : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));
+
+        return $this->output($data, $options);
+    }
+
+    /**
+     * Outputs data as array or string according to options.
+     *
+     * @param array $data
+     * @param array $options
+     *
+     * @return array|string
+     */
+    private function output(array $data, array $options)
+    {
+        if (isset($options['as_array']) && $options['as_array']) {
+            return $data;
+        }
+
+        return json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0);
+    }
+}

+ 129 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/MarkdownDescriptor.php

@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * Markdown descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class MarkdownDescriptor extends Descriptor
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputArgument(InputArgument $argument, array $options = array())
+    {
+        return '**'.$argument->getName().':**'."\n\n"
+            .'* Name: '.($argument->getName() ?: '<none>')."\n"
+            .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
+            .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
+            .'* Description: '.($argument->getDescription() ?: '<none>')."\n"
+            .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputOption(InputOption $option, array $options = array())
+    {
+        return '**'.$option->getName().':**'."\n\n"
+            .'* Name: `--'.$option->getName().'`'."\n"
+            .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '<none>')."\n"
+            .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
+            .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
+            .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
+            .'* Description: '.($option->getDescription() ?: '<none>')."\n"
+            .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+    {
+        $blocks = array();
+
+        if (count($definition->getArguments()) > 0) {
+            $blocks[] = '### Arguments:';
+            foreach ($definition->getArguments() as $argument) {
+                $blocks[] = $this->describeInputArgument($argument);
+            }
+        }
+
+        if (count($definition->getOptions()) > 0) {
+            $blocks[] = '### Options:';
+            foreach ($definition->getOptions() as $option) {
+                $blocks[] = $this->describeInputOption($option);
+            }
+        }
+
+        return implode("\n\n", $blocks);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeCommand(Command $command, array $options = array())
+    {
+        $command->getSynopsis();
+        $command->mergeApplicationDefinition(false);
+
+        $markdown = $command->getName()."\n"
+            .str_repeat('-', strlen($command->getName()))."\n\n"
+            .'* Description: '.($command->getDescription() ?: '<none>')."\n"
+            .'* Usage: `'.$command->getSynopsis().'`'."\n"
+            .'* Aliases: '.(count($command->getAliases()) ? '`'.implode('`, `', $command->getAliases()).'`' : '<none>');
+
+        if ($help = $command->getProcessedHelp()) {
+            $markdown .= "\n\n".$help;
+        }
+
+        if ($definitionMarkdown = $this->describeInputDefinition($command->getNativeDefinition())) {
+            $markdown .= "\n\n".$definitionMarkdown;
+        }
+
+        return $markdown;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeApplication(Application $application, array $options = array())
+    {
+        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+        $description = new ApplicationDescription($application, $describedNamespace);
+        $blocks = array($application->getName()."\n".str_repeat('=', strlen($application->getName())));
+
+        foreach ($description->getNamespaces() as $namespace) {
+            if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+                $blocks[] = '**'.$namespace['id'].':**';
+            }
+
+            $blocks[] = implode("\n", array_map(function ($commandName) {
+                return '* '.$commandName;
+            } , $namespace['commands']));
+        }
+
+        foreach ($description->getCommands() as $command) {
+            $blocks[] = $this->describeCommand($command);
+        }
+
+        return implode("\n\n", $blocks);
+    }
+}

+ 210 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/TextDescriptor.php

@@ -0,0 +1,210 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * Text descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class TextDescriptor extends Descriptor
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputArgument(InputArgument $argument, array $options = array())
+    {
+        if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
+            $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($argument->getDefault()));
+        } else {
+            $default = '';
+        }
+
+        $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($argument->getName());
+        $output = str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $argument->getDescription());
+        $output = sprintf(" <info>%-${nameWidth}s</info> %s%s", $argument->getName(), $output, $default);
+
+        return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputOption(InputOption $option, array $options = array())
+    {
+        if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
+            $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($option->getDefault()));
+        } else {
+            $default = '';
+        }
+
+        $nameWidth = isset($options['name_width']) ? $options['name_width'] : strlen($option->getName());
+        $nameWithShortcutWidth = $nameWidth - strlen($option->getName()) - 2;
+
+        $output = sprintf(" <info>%s</info> %-${nameWithShortcutWidth}s%s%s%s",
+            '--'.$option->getName(),
+            $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '',
+            str_replace("\n", "\n".str_repeat(' ', $nameWidth + 2), $option->getDescription()),
+            $default,
+            $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
+        );
+
+        return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+    {
+        $nameWidth = 0;
+        foreach ($definition->getOptions() as $option) {
+            $nameLength = strlen($option->getName()) + 2;
+            if ($option->getShortcut()) {
+                $nameLength += strlen($option->getShortcut()) + 3;
+            }
+            $nameWidth = max($nameWidth, $nameLength);
+        }
+        foreach ($definition->getArguments() as $argument) {
+            $nameWidth = max($nameWidth, strlen($argument->getName()));
+        }
+        ++$nameWidth;
+
+        $messages = array();
+
+        if ($definition->getArguments()) {
+            $messages[] = '<comment>Arguments:</comment>';
+            foreach ($definition->getArguments() as $argument) {
+                $messages[] = $this->describeInputArgument($argument, array('name_width' => $nameWidth));
+            }
+            $messages[] = '';
+        }
+
+        if ($definition->getOptions()) {
+            $messages[] = '<comment>Options:</comment>';
+            foreach ($definition->getOptions() as $option) {
+                $messages[] = $this->describeInputOption($option, array('name_width' => $nameWidth));
+            }
+            $messages[] = '';
+        }
+
+        $output = implode("\n", $messages);
+
+        return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeCommand(Command $command, array $options = array())
+    {
+        $command->getSynopsis();
+        $command->mergeApplicationDefinition(false);
+        $messages = array('<comment>Usage:</comment>', ' '.$command->getSynopsis(), '');
+
+        if ($command->getAliases()) {
+            $messages[] = '<comment>Aliases:</comment> <info>'.implode(', ', $command->getAliases()).'</info>';
+        }
+
+        $messages[] = $this->describeInputDefinition($command->getNativeDefinition());
+
+        if ($help = $command->getProcessedHelp()) {
+            $messages[] = '<comment>Help:</comment>';
+            $messages[] = ' '.str_replace("\n", "\n ", $help)."\n";
+        }
+
+        $output = implode("\n", $messages);
+
+        return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeApplication(Application $application, array $options = array())
+    {
+        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+        $description = new ApplicationDescription($application, $describedNamespace);
+        $messages = array();
+
+        if (isset($options['raw_text']) && $options['raw_text']) {
+            $width = $this->getColumnWidth($description->getCommands());
+
+            foreach ($description->getCommands() as $command) {
+                $messages[] = sprintf("%-${width}s %s", $command->getName(), $command->getDescription());
+            }
+        } else {
+            $width = $this->getColumnWidth($description->getCommands());
+
+            $messages[] = $application->getHelp();
+            $messages[] = '';
+
+            if ($describedNamespace) {
+                $messages[] = sprintf("<comment>Available commands for the \"%s\" namespace:</comment>", $describedNamespace);
+            } else {
+                $messages[] = '<comment>Available commands:</comment>';
+            }
+
+            // add commands by namespace
+            foreach ($description->getNamespaces() as $namespace) {
+                if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+                    $messages[] = '<comment>'.$namespace['id'].'</comment>';
+                }
+
+                foreach ($namespace['commands'] as $name) {
+                    $messages[] = sprintf("  <info>%-${width}s</info> %s", $name, $description->getCommand($name)->getDescription());
+                }
+            }
+        }
+
+        $output = implode("\n", $messages);
+
+        return isset($options['raw_text']) && $options['raw_text'] ? strip_tags($output) : $output;
+    }
+
+    /**
+     * Formats input option/argument default value.
+     *
+     * @param mixed $default
+     *
+     * @return string
+     */
+    private function formatDefaultValue($default)
+    {
+        if (version_compare(PHP_VERSION, '5.4', '<')) {
+            return str_replace('\/', '/', json_encode($default));
+        }
+
+        return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+    }
+
+    /**
+     * @param Command[] $commands
+     *
+     * @return int
+     */
+    private function getColumnWidth(array $commands)
+    {
+        $width = 0;
+        foreach ($commands as $command) {
+            $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
+        }
+
+        return $width + 2;
+    }
+}

+ 212 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Descriptor/XmlDescriptor.php

@@ -0,0 +1,212 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * XML descriptor.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class XmlDescriptor extends Descriptor
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputArgument(InputArgument $argument, array $options = array())
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+
+        $dom->appendChild($objectXML = $dom->createElement('argument'));
+        $objectXML->setAttribute('name', $argument->getName());
+        $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
+        $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
+        $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+        $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
+
+        $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+        $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
+        foreach ($defaults as $default) {
+            $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+            $defaultXML->appendChild($dom->createTextNode($default));
+        }
+
+        return $this->output($dom, $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputOption(InputOption $option, array $options = array())
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+
+        $dom->appendChild($objectXML = $dom->createElement('option'));
+        $objectXML->setAttribute('name', '--'.$option->getName());
+        $pos = strpos($option->getShortcut(), '|');
+        if (false !== $pos) {
+            $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
+            $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
+        } else {
+            $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
+        }
+        $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
+        $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
+        $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
+        $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+        $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
+
+        if ($option->acceptValue()) {
+            $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
+            $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+
+            if (!empty($defaults)) {
+                foreach ($defaults as $default) {
+                    $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+                    $defaultXML->appendChild($dom->createTextNode($default));
+                }
+            }
+        }
+
+        return $this->output($dom, $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->appendChild($definitionXML = $dom->createElement('definition'));
+
+        $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
+        foreach ($definition->getArguments() as $argument) {
+            $this->appendDocument($argumentsXML, $this->describeInputArgument($argument, array('as_dom' => true)));
+        }
+
+        $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
+        foreach ($definition->getOptions() as $option) {
+            $this->appendDocument($optionsXML, $this->describeInputOption($option, array('as_dom' => true)));
+        }
+
+        return $this->output($dom, $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeCommand(Command $command, array $options = array())
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->appendChild($commandXML = $dom->createElement('command'));
+
+        $command->getSynopsis();
+        $command->mergeApplicationDefinition(false);
+
+        $commandXML->setAttribute('id', $command->getName());
+        $commandXML->setAttribute('name', $command->getName());
+
+        $commandXML->appendChild($usageXML = $dom->createElement('usage'));
+        $usageXML->appendChild($dom->createTextNode(sprintf($command->getSynopsis(), '')));
+
+        $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
+        $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));
+
+        $commandXML->appendChild($helpXML = $dom->createElement('help'));
+        $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));
+
+        $commandXML->appendChild($aliasesXML = $dom->createElement('aliases'));
+        foreach ($command->getAliases() as $alias) {
+            $aliasesXML->appendChild($aliasXML = $dom->createElement('alias'));
+            $aliasXML->appendChild($dom->createTextNode($alias));
+        }
+
+        $definitionXML = $this->describeInputDefinition($command->getNativeDefinition(), array('as_dom' => true));
+        $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
+
+        return $this->output($dom, $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function describeApplication(Application $application, array $options = array())
+    {
+        $dom = new \DOMDocument('1.0', 'UTF-8');
+        $dom->appendChild($rootXml = $dom->createElement('symfony'));
+        $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
+
+        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+        $description = new ApplicationDescription($application, $describedNamespace);
+
+        if ($describedNamespace) {
+            $commandsXML->setAttribute('namespace', $describedNamespace);
+        }
+
+        foreach ($description->getCommands() as $command) {
+            $this->appendDocument($commandsXML, $this->describeCommand($command, array('as_dom' => true)));
+        }
+
+        if (!$describedNamespace) {
+            $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
+
+            foreach ($description->getNamespaces() as $namespace) {
+                $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
+                $namespaceArrayXML->setAttribute('id', $namespace['id']);
+
+                foreach ($namespace['commands'] as $name) {
+                    $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
+                    $commandXML->appendChild($dom->createTextNode($name));
+                }
+            }
+        }
+
+        return $this->output($dom, $options);
+    }
+
+    /**
+     * Appends document children to parent node.
+     *
+     * @param \DOMNode $parentNode
+     * @param \DOMNode $importedParent
+     */
+    private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
+    {
+        foreach ($importedParent->childNodes as $childNode) {
+            $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
+        }
+    }
+
+    /**
+     * Outputs document as DOMDocument or string according to options.
+     *
+     * @param \DOMDocument $dom
+     * @param array        $options
+     *
+     * @return \DOMDocument|string
+     */
+    private function output(\DOMDocument $dom, array $options)
+    {
+        if (isset($options['as_dom']) && $options['as_dom']) {
+            return $dom;
+        }
+
+        $dom->formatOutput = true;
+
+        return $dom->saveXML();
+    }
+}

+ 67 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Event/ConsoleExceptionEvent.php

@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Allows to handle exception thrown in a command.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConsoleExceptionEvent extends ConsoleEvent
+{
+    private $exception;
+    private $exitCode;
+
+    public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
+    {
+        parent::__construct($command, $input, $output);
+
+        $this->setException($exception);
+        $this->exitCode = (int) $exitCode;
+    }
+
+    /**
+     * Returns the thrown exception.
+     *
+     * @return \Exception The thrown exception
+     */
+    public function getException()
+    {
+        return $this->exception;
+    }
+
+    /**
+     * Replaces the thrown exception.
+     *
+     * This exception will be thrown if no response is set in the event.
+     *
+     * @param \Exception $exception The thrown exception
+     */
+    public function setException(\Exception $exception)
+    {
+        $this->exception = $exception;
+    }
+
+    /**
+     * Gets the exit code.
+     *
+     * @return integer The command exit code
+     */
+    public function getExitCode()
+    {
+        return $this->exitCode;
+    }
+}

+ 95 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Helper/DescriptorHelper.php

@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Descriptor\DescriptorInterface;
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * This class adds helper method to describe objects in various formats.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class DescriptorHelper extends Helper
+{
+    /**
+     * @var DescriptorInterface[]
+     */
+    private $descriptors = array();
+
+    /**
+     * Constructor.
+     */
+    public function __construct()
+    {
+        $this
+            ->register('txt',  new TextDescriptor())
+            ->register('xml',  new XmlDescriptor())
+            ->register('json', new JsonDescriptor())
+            ->register('md',   new MarkdownDescriptor())
+        ;
+    }
+
+    /**
+     * Describes an object if supported.
+     *
+     * @param OutputInterface $output
+     * @param object          $object
+     * @param string          $format
+     * @param boolean         $raw
+     */
+    public function describe(OutputInterface $output, $object, $format = null, $raw = false, $namespace = null)
+    {
+        $options = array('raw_text' => $raw, 'format' => $format ?: 'txt', 'namespace' => $namespace);
+        $type = !$raw && 'txt' === $options['format'] ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW;
+
+        if (!isset($this->descriptors[$options['format']])) {
+            throw new \InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
+        }
+
+        $descriptor = $this->descriptors[$options['format']];
+
+        $output->writeln($descriptor->describe($object, $options), $type);
+    }
+
+    /**
+     * Registers a descriptor.
+     *
+     * @param string              $format
+     * @param DescriptorInterface $descriptor
+     *
+     * @return DescriptorHelper
+     */
+    public function register($format, DescriptorInterface $descriptor)
+    {
+        $this->descriptors[$format] = $descriptor;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'descriptor';
+    }
+}

+ 98 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/AbstractDescriptorTest.php

@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Descriptor\DescriptorInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @dataProvider getDescribeInputArgumentTestData */
+    public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
+    {
+        $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($argument)));
+    }
+
+    /** @dataProvider getDescribeInputOptionTestData */
+    public function testDescribeInputOption(InputOption $option, $expectedDescription)
+    {
+        $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($option)));
+    }
+
+    /** @dataProvider getDescribeInputDefinitionTestData */
+    public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription)
+    {
+        $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($definition)));
+    }
+
+    /** @dataProvider getDescribeCommandTestData */
+    public function testDescribeCommand(Command $command, $expectedDescription)
+    {
+        $this->assertEquals(trim($expectedDescription), trim($this->getDescriptor()->describe($command)));
+    }
+
+    /** @dataProvider getDescribeApplicationTestData */
+    public function testDescribeApplication(Application $application, $expectedDescription)
+    {
+        // Replaces the dynamic placeholders of the command help text with a static version.
+        // The placeholder %command.full_name% includes the script path that is not predictable
+        // and can not be tested against.
+        foreach ($application->all() as $command) {
+            $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+        }
+
+        $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $this->getDescriptor()->describe($application))));
+    }
+
+    public function getDescribeInputArgumentTestData()
+    {
+        return $this->getDescriptionTestData(ObjectsProvider::getInputArguments());
+    }
+
+    public function getDescribeInputOptionTestData()
+    {
+        return $this->getDescriptionTestData(ObjectsProvider::getInputOptions());
+    }
+
+    public function getDescribeInputDefinitionTestData()
+    {
+        return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions());
+    }
+
+    public function getDescribeCommandTestData()
+    {
+        return $this->getDescriptionTestData(ObjectsProvider::getCommands());
+    }
+
+    public function getDescribeApplicationTestData()
+    {
+        return $this->getDescriptionTestData(ObjectsProvider::getApplications());
+    }
+
+    abstract protected function getDescriptor();
+    abstract protected function getFormat();
+
+    private function getDescriptionTestData(array $objects)
+    {
+        $data = array();
+        foreach ($objects as $name => $object) {
+            $description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat()));
+            $data[] = array($object, $description);
+        }
+
+        return $data;
+    }
+}

+ 27 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/JsonDescriptorTest.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+
+class JsonDescriptorTest extends AbstractDescriptorTest
+{
+    protected function getDescriptor()
+    {
+        return new JsonDescriptor();
+    }
+
+    protected function getFormat()
+    {
+        return 'json';
+    }
+}

+ 27 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/MarkdownDescriptorTest.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+
+class MarkdownDescriptorTest extends AbstractDescriptorTest
+{
+    protected function getDescriptor()
+    {
+        return new MarkdownDescriptor();
+    }
+
+    protected function getFormat()
+    {
+        return 'md';
+    }
+}

+ 75 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/ObjectsProvider.php

@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2;
+use Symfony\Component\Finder\Shell\Command;
+
+/**
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class ObjectsProvider
+{
+    public static function getInputArguments()
+    {
+        return array(
+            'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED),
+            'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
+            'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
+        );
+    }
+
+    public static function getInputOptions()
+    {
+        return array(
+            'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+            'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'),
+            'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
+            'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
+        );
+    }
+
+    public static function getInputDefinitions()
+    {
+        return array(
+            'input_definition_1' => new InputDefinition(),
+            'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))),
+            'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))),
+            'input_definition_4' => new InputDefinition(array(
+                new InputArgument('argument_name', InputArgument::REQUIRED),
+                new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+            )),
+        );
+    }
+
+    public static function getCommands()
+    {
+        return array(
+            'command_1' => new DescriptorCommand1(),
+            'command_2' => new DescriptorCommand2(),
+        );
+    }
+
+    public static function getApplications()
+    {
+        return array(
+            'application_1' => new DescriptorApplication1(),
+            'application_2' => new DescriptorApplication2(),
+        );
+    }
+}

+ 27 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/TextDescriptorTest.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+
+class TextDescriptorTest extends AbstractDescriptorTest
+{
+    protected function getDescriptor()
+    {
+        return new TextDescriptor();
+    }
+
+    protected function getFormat()
+    {
+        return 'txt';
+    }
+}

+ 27 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Descriptor/XmlDescriptorTest.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+
+class XmlDescriptorTest extends AbstractDescriptorTest
+{
+    protected function getDescriptor()
+    {
+        return new XmlDescriptor();
+    }
+
+    protected function getFormat()
+    {
+        return 'xml';
+    }
+}

+ 18 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication1.php

@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication1 extends Application
+{
+}

+ 24 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorApplication2.php

@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication2 extends Application
+{
+    public function __construct()
+    {
+        parent::__construct('My Symfony application', 'v1.0');
+        $this->add(new DescriptorCommand1());
+        $this->add(new DescriptorCommand2());
+    }
+}

+ 27 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand1.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+
+class DescriptorCommand1 extends Command
+{
+    protected function configure()
+    {
+        $this
+            ->setName('descriptor:command1')
+            ->setAliases(array('alias1', 'alias2'))
+            ->setDescription('command 1 description')
+            ->setHelp('command 1 help')
+        ;
+    }
+}

+ 30 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/DescriptorCommand2.php

@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class DescriptorCommand2 extends Command
+{
+    protected function configure()
+    {
+        $this
+            ->setName('descriptor:command2')
+            ->setDescription('command 2 description')
+            ->setHelp('command 2 help')
+            ->addArgument('argument_name', InputArgument::REQUIRED)
+            ->addOption('option_name', 'o', InputOption::VALUE_NONE)
+        ;
+    }
+}

File diff suppressed because it is too large
+ 0 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.json


+ 199 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.md

@@ -0,0 +1,199 @@
+UNKNOWN
+=======
+
+* help
+* list
+
+help
+----
+
+* Description: Displays help for a command
+* Usage: `help [--xml] [--format="..."] [--raw] [command_name]`
+* Aliases: <none>
+
+The <info>help</info> command displays help for a given command:
+
+  <info>php app/console help list</info>
+
+You can also output the help in other formats by using the <comment>--format</comment> option:
+
+  <info>php app/console help --format=xml list</info>
+
+To display the list of available commands, please use the <info>list</info> command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output help as XML
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output help in other formats
+* Default: `NULL`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage: `list [--xml] [--raw] [--format="..."] [namespace]`
+* Aliases: <none>
+
+The <info>list</info> command lists all commands:
+
+  <info>php app/console list</info>
+
+You can also display the commands for a specific namespace:
+
+  <info>php app/console list test</info>
+
+You can also output the information in other formats by using the <comment>--format</comment> option:
+
+  <info>php app/console list --format=xml</info>
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+  <info>php app/console list --raw</info>
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output list as XML
+* Default: `false`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output list in other formats
+* Default: `NULL`

+ 17 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.txt

@@ -0,0 +1,17 @@
+<info>Console Tool</info>
+
+<comment>Usage:</comment>
+  [options] command [arguments]
+
+<comment>Options:</comment>
+  <info>--help</info>           <info>-h</info> Display this help message.
+  <info>--quiet</info>          <info>-q</info> Do not output any message.
+  <info>--verbose</info>        <info>-v|vv|vvv</info> Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+  <info>--version</info>        <info>-V</info> Display this application version.
+  <info>--ansi</info>              Force ANSI output.
+  <info>--no-ansi</info>           Disable ANSI output.
+  <info>--no-interaction</info> <info>-n</info> Do not ask any interactive question.
+
+<comment>Available commands:</comment>
+  <info>help  </info> Displays help for a command
+  <info>list  </info> Lists commands

+ 104 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_1.xml

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<symfony>
+  <commands>
+    <command id="help" name="help">
+      <usage>help [--xml] [--format="..."] [--raw] [command_name]</usage>
+      <description>Displays help for a command</description>
+      <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
+ 
+   &lt;info&gt;php app/console help list&lt;/info&gt;
+ 
+ You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+ 
+   &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
+ 
+ To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
+      <aliases/>
+      <arguments>
+        <argument name="command_name" is_required="0" is_array="0">
+          <description>The command name</description>
+          <defaults>
+            <default>help</default>
+          </defaults>
+        </argument>
+      </arguments>
+      <options>
+        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output help as XML</description>
+        </option>
+        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+          <description>To output help in other formats</description>
+          <defaults/>
+        </option>
+        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output raw command help</description>
+        </option>
+        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this help message.</description>
+        </option>
+        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not output any message.</description>
+        </option>
+        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+        </option>
+        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this application version.</description>
+        </option>
+        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Force ANSI output.</description>
+        </option>
+        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Disable ANSI output.</description>
+        </option>
+        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not ask any interactive question.</description>
+        </option>
+      </options>
+    </command>
+    <command id="list" name="list">
+      <usage>list [--xml] [--raw] [--format="..."] [namespace]</usage>
+      <description>Lists commands</description>
+      <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
+ 
+   &lt;info&gt;php app/console list&lt;/info&gt;
+ 
+ You can also display the commands for a specific namespace:
+ 
+   &lt;info&gt;php app/console list test&lt;/info&gt;
+ 
+ You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+ 
+   &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
+ 
+ It's also possible to get raw list of commands (useful for embedding command runner):
+ 
+   &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
+      <aliases/>
+      <arguments>
+        <argument name="namespace" is_required="0" is_array="0">
+          <description>The namespace name</description>
+          <defaults/>
+        </argument>
+      </arguments>
+      <options>
+        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output list as XML</description>
+        </option>
+        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output raw command list</description>
+        </option>
+        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+          <description>To output list in other formats</description>
+          <defaults/>
+        </option>
+      </options>
+    </command>
+  </commands>
+  <namespaces>
+    <namespace id="_global">
+      <command>help</command>
+      <command>list</command>
+    </namespace>
+  </namespaces>
+</symfony>

File diff suppressed because it is too large
+ 0 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.json


+ 388 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.md

@@ -0,0 +1,388 @@
+My Symfony application
+======================
+
+* alias1
+* alias2
+* help
+* list
+
+**descriptor:**
+
+* descriptor:command1
+* descriptor:command2
+
+help
+----
+
+* Description: Displays help for a command
+* Usage: `help [--xml] [--format="..."] [--raw] [command_name]`
+* Aliases: <none>
+
+The <info>help</info> command displays help for a given command:
+
+  <info>php app/console help list</info>
+
+You can also output the help in other formats by using the <comment>--format</comment> option:
+
+  <info>php app/console help --format=xml list</info>
+
+To display the list of available commands, please use the <info>list</info> command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output help as XML
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output help in other formats
+* Default: `NULL`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage: `list [--xml] [--raw] [--format="..."] [namespace]`
+* Aliases: <none>
+
+The <info>list</info> command lists all commands:
+
+  <info>php app/console list</info>
+
+You can also display the commands for a specific namespace:
+
+  <info>php app/console list test</info>
+
+You can also output the information in other formats by using the <comment>--format</comment> option:
+
+  <info>php app/console list --format=xml</info>
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+  <info>php app/console list --raw</info>
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**xml:**
+
+* Name: `--xml`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output list as XML
+* Default: `false`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut: <none>
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: To output list in other formats
+* Default: `NULL`
+
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage: `descriptor:command1`
+* Aliases: `alias1`, `alias2`
+
+command 1 help
+
+### Options:
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`
+
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage: `descriptor:command2 [-o|--option_name] argument_name`
+* Aliases: <none>
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message.
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message.
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version.
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output.
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut: <none>
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output.
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question.
+* Default: `false`

+ 22 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.txt

@@ -0,0 +1,22 @@
+<info>My Symfony application</info> version <comment>v1.0</comment>
+
+<comment>Usage:</comment>
+  [options] command [arguments]
+
+<comment>Options:</comment>
+  <info>--help</info>           <info>-h</info> Display this help message.
+  <info>--quiet</info>          <info>-q</info> Do not output any message.
+  <info>--verbose</info>        <info>-v|vv|vvv</info> Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+  <info>--version</info>        <info>-V</info> Display this application version.
+  <info>--ansi</info>              Force ANSI output.
+  <info>--no-ansi</info>           Disable ANSI output.
+  <info>--no-interaction</info> <info>-n</info> Do not ask any interactive question.
+
+<comment>Available commands:</comment>
+  <info>alias1               </info> command 1 description
+  <info>alias2               </info> command 1 description
+  <info>help                 </info> Displays help for a command
+  <info>list                 </info> Lists commands
+<comment>descriptor</comment>
+  <info>descriptor:command1  </info> command 1 description
+  <info>descriptor:command2  </info> command 2 description

+ 181 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/application_2.xml

@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<symfony>
+  <commands>
+    <command id="help" name="help">
+      <usage>help [--xml] [--format="..."] [--raw] [command_name]</usage>
+      <description>Displays help for a command</description>
+      <help>The &lt;info&gt;help&lt;/info&gt; command displays help for a given command:
+ 
+   &lt;info&gt;php app/console help list&lt;/info&gt;
+ 
+ You can also output the help in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+ 
+   &lt;info&gt;php app/console help --format=xml list&lt;/info&gt;
+ 
+ To display the list of available commands, please use the &lt;info&gt;list&lt;/info&gt; command.</help>
+      <aliases/>
+      <arguments>
+        <argument name="command_name" is_required="0" is_array="0">
+          <description>The command name</description>
+          <defaults>
+            <default>help</default>
+          </defaults>
+        </argument>
+      </arguments>
+      <options>
+        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output help as XML</description>
+        </option>
+        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+          <description>To output help in other formats</description>
+          <defaults/>
+        </option>
+        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output raw command help</description>
+        </option>
+        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this help message.</description>
+        </option>
+        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not output any message.</description>
+        </option>
+        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+        </option>
+        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this application version.</description>
+        </option>
+        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Force ANSI output.</description>
+        </option>
+        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Disable ANSI output.</description>
+        </option>
+        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not ask any interactive question.</description>
+        </option>
+      </options>
+    </command>
+    <command id="list" name="list">
+      <usage>list [--xml] [--raw] [--format="..."] [namespace]</usage>
+      <description>Lists commands</description>
+      <help>The &lt;info&gt;list&lt;/info&gt; command lists all commands:
+ 
+   &lt;info&gt;php app/console list&lt;/info&gt;
+ 
+ You can also display the commands for a specific namespace:
+ 
+   &lt;info&gt;php app/console list test&lt;/info&gt;
+ 
+ You can also output the information in other formats by using the &lt;comment&gt;--format&lt;/comment&gt; option:
+ 
+   &lt;info&gt;php app/console list --format=xml&lt;/info&gt;
+ 
+ It's also possible to get raw list of commands (useful for embedding command runner):
+ 
+   &lt;info&gt;php app/console list --raw&lt;/info&gt;</help>
+      <aliases/>
+      <arguments>
+        <argument name="namespace" is_required="0" is_array="0">
+          <description>The namespace name</description>
+          <defaults/>
+        </argument>
+      </arguments>
+      <options>
+        <option name="--xml" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output list as XML</description>
+        </option>
+        <option name="--raw" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>To output raw command list</description>
+        </option>
+        <option name="--format" shortcut="" accept_value="1" is_value_required="1" is_multiple="0">
+          <description>To output list in other formats</description>
+          <defaults/>
+        </option>
+      </options>
+    </command>
+    <command id="descriptor:command1" name="descriptor:command1">
+      <usage>descriptor:command1</usage>
+      <description>command 1 description</description>
+      <help>command 1 help</help>
+      <aliases>
+        <alias>alias1</alias>
+        <alias>alias2</alias>
+      </aliases>
+      <arguments/>
+      <options>
+        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this help message.</description>
+        </option>
+        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not output any message.</description>
+        </option>
+        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+        </option>
+        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this application version.</description>
+        </option>
+        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Force ANSI output.</description>
+        </option>
+        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Disable ANSI output.</description>
+        </option>
+        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not ask any interactive question.</description>
+        </option>
+      </options>
+    </command>
+    <command id="descriptor:command2" name="descriptor:command2">
+      <usage>descriptor:command2 [-o|--option_name] argument_name</usage>
+      <description>command 2 description</description>
+      <help>command 2 help</help>
+      <aliases/>
+      <arguments>
+        <argument name="argument_name" is_required="1" is_array="0">
+          <description></description>
+          <defaults/>
+        </argument>
+      </arguments>
+      <options>
+        <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+          <description></description>
+        </option>
+        <option name="--help" shortcut="-h" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this help message.</description>
+        </option>
+        <option name="--quiet" shortcut="-q" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not output any message.</description>
+        </option>
+        <option name="--verbose" shortcut="-v" shortcuts="-v|-vv|-vvv" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</description>
+        </option>
+        <option name="--version" shortcut="-V" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Display this application version.</description>
+        </option>
+        <option name="--ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Force ANSI output.</description>
+        </option>
+        <option name="--no-ansi" shortcut="" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Disable ANSI output.</description>
+        </option>
+        <option name="--no-interaction" shortcut="-n" accept_value="0" is_value_required="0" is_multiple="0">
+          <description>Do not ask any interactive question.</description>
+        </option>
+      </options>
+    </command>
+  </commands>
+  <namespaces>
+    <namespace id="_global">
+      <command>alias1</command>
+      <command>alias2</command>
+      <command>help</command>
+      <command>list</command>
+    </namespace>
+    <namespace id="descriptor">
+      <command>descriptor:command1</command>
+      <command>descriptor:command2</command>
+    </namespace>
+  </namespaces>
+</symfony>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.json

@@ -0,0 +1 @@
+{"name":"descriptor:command1","usage":"descriptor:command1","description":"command 1 description","help":"command 1 help","aliases":["alias1","alias2"],"definition":{"arguments":[],"options":[]}}

+ 8 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.md

@@ -0,0 +1,8 @@
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage: `descriptor:command1`
+* Aliases: `alias1`, `alias2`
+
+command 1 help

+ 7 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.txt

@@ -0,0 +1,7 @@
+<comment>Usage:</comment>
+ descriptor:command1
+
+<comment>Aliases:</comment> <info>alias1, alias2</info>
+
+<comment>Help:</comment>
+ command 1 help

+ 12 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_1.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<command id="descriptor:command1" name="descriptor:command1">
+  <usage>descriptor:command1</usage>
+  <description>command 1 description</description>
+  <help>command 1 help</help>
+  <aliases>
+    <alias>alias1</alias>
+    <alias>alias2</alias>
+  </aliases>
+  <arguments/>
+  <options/>
+</command>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.json

@@ -0,0 +1 @@
+{"name":"descriptor:command2","usage":"descriptor:command2 [-o|--option_name] argument_name","description":"command 2 description","help":"command 2 help","aliases":[],"definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}}

+ 30 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.md

@@ -0,0 +1,30 @@
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage: `descriptor:command2 [-o|--option_name] argument_name`
+* Aliases: <none>
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`

+ 11 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.txt

@@ -0,0 +1,11 @@
+<comment>Usage:</comment>
+ descriptor:command2 [-o|--option_name] argument_name
+
+<comment>Arguments:</comment>
+ <info>argument_name     </info> 
+
+<comment>Options:</comment>
+ <info>--option_name</info> (-o) 
+
+<comment>Help:</comment>
+ command 2 help

+ 18 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/command_2.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<command id="descriptor:command2" name="descriptor:command2">
+  <usage>descriptor:command2 [-o|--option_name] argument_name</usage>
+  <description>command 2 description</description>
+  <help>command 2 help</help>
+  <aliases/>
+  <arguments>
+    <argument name="argument_name" is_required="1" is_array="0">
+      <description></description>
+      <defaults/>
+    </argument>
+  </arguments>
+  <options>
+    <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+      <description></description>
+    </option>
+  </options>
+</command>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.json

@@ -0,0 +1 @@
+{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}

+ 7 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.md

@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.txt

@@ -0,0 +1 @@
+ <info>argument_name</info>

+ 5 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_1.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<argument name="argument_name" is_required="1" is_array="0">
+  <description></description>
+  <defaults/>
+</argument>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.json

@@ -0,0 +1 @@
+{"name":"argument_name","is_required":false,"is_array":true,"description":"argument description","default":[]}

+ 7 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.md

@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: yes
+* Description: argument description
+* Default: `array ()`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.txt

@@ -0,0 +1 @@
+ <info>argument_name</info> argument description

+ 5 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_2.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<argument name="argument_name" is_required="0" is_array="1">
+  <description>argument description</description>
+  <defaults/>
+</argument>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.json

@@ -0,0 +1 @@
+{"name":"argument_name","is_required":false,"is_array":false,"description":"argument description","default":"default_value"}

+ 7 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.md

@@ -0,0 +1,7 @@
+**argument_name:**
+
+* Name: argument_name
+* Is required: no
+* Is array: no
+* Description: argument description
+* Default: `'default_value'`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.txt

@@ -0,0 +1 @@
+ <info>argument_name</info> argument description<comment> (default: "default_value")</comment>

+ 7 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_argument_3.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<argument name="argument_name" is_required="0" is_array="0">
+  <description>argument description</description>
+  <defaults>
+    <default>default_value</default>
+  </defaults>
+</argument>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.json

@@ -0,0 +1 @@
+{"arguments":[],"options":[]}

+ 0 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.md


+ 0 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.txt


+ 5 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_1.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+  <arguments/>
+  <options/>
+</definition>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.json

@@ -0,0 +1 @@
+{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":[]}

+ 9 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.md

@@ -0,0 +1,9 @@
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`

+ 2 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.txt

@@ -0,0 +1,2 @@
+<comment>Arguments:</comment>
+ <info>argument_name </info>

+ 10 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_2.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+  <arguments>
+    <argument name="argument_name" is_required="1" is_array="0">
+      <description></description>
+      <defaults/>
+    </argument>
+  </arguments>
+  <options/>
+</definition>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.json

@@ -0,0 +1 @@
+{"arguments":[],"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}

+ 11 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.md

@@ -0,0 +1,11 @@
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`

+ 2 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.txt

@@ -0,0 +1,2 @@
+<comment>Options:</comment>
+ <info>--option_name</info> (-o)

+ 9 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_3.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+  <arguments/>
+  <options>
+    <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+      <description></description>
+    </option>
+  </options>
+</definition>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.json

@@ -0,0 +1 @@
+{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}}}

+ 21 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.md

@@ -0,0 +1,21 @@
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description: <none>
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`

+ 5 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.txt

@@ -0,0 +1,5 @@
+<comment>Arguments:</comment>
+ <info>argument_name     </info> 
+
+<comment>Options:</comment>
+ <info>--option_name</info> (-o)

+ 14 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_definition_4.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definition>
+  <arguments>
+    <argument name="argument_name" is_required="1" is_array="0">
+      <description></description>
+      <defaults/>
+    </argument>
+  </arguments>
+  <options>
+    <option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+      <description></description>
+    </option>
+  </options>
+</definition>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.json

@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false}

+ 9 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.md

@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: <none>
+* Default: `false`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.txt

@@ -0,0 +1 @@
+ <info>--option_name</info> (-o)

+ 4 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_1.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="0" is_value_required="0" is_multiple="0">
+  <description></description>
+</option>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.json

@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":false,"description":"option description","default":"default_value"}

+ 9 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.md

@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: no
+* Description: option description
+* Default: `'default_value'`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.txt

@@ -0,0 +1 @@
+ <info>--option_name</info> (-o) option description<comment> (default: "default_value")</comment>

+ 7 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_2.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="0">
+  <description>option description</description>
+  <defaults>
+    <default>default_value</default>
+  </defaults>
+</option>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.json

@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"option description","default":null}

+ 9 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.md

@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: option description
+* Default: `NULL`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.txt

@@ -0,0 +1 @@
+ <info>--option_name</info> (-o) option description

+ 5 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_3.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="1" is_multiple="0">
+  <description>option description</description>
+  <defaults/>
+</option>

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.json

@@ -0,0 +1 @@
+{"name":"--option_name","shortcut":"-o","accept_value":true,"is_value_required":false,"is_multiple":true,"description":"option description","default":[]}

+ 9 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.md

@@ -0,0 +1,9 @@
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: yes
+* Is value required: no
+* Is multiple: yes
+* Description: option description
+* Default: `array ()`

+ 1 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.txt

@@ -0,0 +1 @@
+ <info>--option_name</info> (-o) option description<comment> (multiple values allowed)</comment>

+ 5 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Fixtures/input_option_4.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="1">
+  <description>option description</description>
+  <defaults/>
+</option>

+ 136 - 0
vendor/chamilo/chash/vendor/symfony/console/Symfony/Component/Console/Tests/Helper/HelperSetTest.php

@@ -0,0 +1,136 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Helper;
+
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Command\Command;
+
+class HelperSetTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers \Symfony\Component\Console\Helper\HelperSet::__construct
+     */
+    public function testConstructor()
+    {
+        $mock_helper = $this->getGenericMockHelper('fake_helper');
+        $helperset = new HelperSet(array('fake_helper_alias' => $mock_helper));
+
+        $this->assertEquals($mock_helper, $helperset->get('fake_helper_alias'), '__construct sets given helper to helpers');
+        $this->assertTrue($helperset->has('fake_helper_alias'), '__construct sets helper alias for given helper');
+    }
+
+    /**
+     * @covers \Symfony\Component\Console\Helper\HelperSet::set
+     */
+    public function testSet()
+    {
+        $helperset = new HelperSet();
+        $helperset->set($this->getGenericMockHelper('fake_helper', $helperset));
+        $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper to helpers');
+
+        $helperset = new HelperSet();
+        $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset));
+        $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset));
+        $this->assertTrue($helperset->has('fake_helper_01'), '->set() will set multiple helpers on consecutive calls');
+        $this->assertTrue($helperset->has('fake_helper_02'), '->set() will set multiple helpers on consecutive calls');
+
+        $helperset = new HelperSet();
+        $helperset->set($this->getGenericMockHelper('fake_helper', $helperset), 'fake_helper_alias');
+        $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper alias when set');
+        $this->assertTrue($helperset->has('fake_helper_alias'), '->set() adds helper alias when set');
+    }
+
+    /**
+     * @covers \Symfony\Component\Console\Helper\HelperSet::has
+     */
+    public function testHas()
+    {
+        $helperset = new HelperSet(array('fake_helper_alias' => $this->getGenericMockHelper('fake_helper')));
+        $this->assertTrue($helperset->has('fake_helper'), '->has() finds set helper');
+        $this->assertTrue($helperset->has('fake_helper_alias'), '->has() finds set helper by alias');
+    }
+
+    /**
+     * @covers \Symfony\Component\Console\Helper\HelperSet::get
+     */
+    public function testGet()
+    {
+        $helper_01 = $this->getGenericMockHelper('fake_helper_01');
+        $helper_02 = $this->getGenericMockHelper('fake_helper_02');
+        $helperset = new HelperSet(array('fake_helper_01_alias' => $helper_01, 'fake_helper_02_alias' => $helper_02));
+        $this->assertEquals($helper_01, $helperset->get('fake_helper_01'), '->get() returns correct helper by name');
+        $this->assertEquals($helper_01, $helperset->get('fake_helper_01_alias'), '->get() returns correct helper by alias');
+        $this->assertEquals($helper_02, $helperset->get('fake_helper_02'), '->get() returns correct helper by name');
+        $this->assertEquals($helper_02, $helperset->get('fake_helper_02_alias'), '->get() returns correct helper by alias');
+
+        $helperset = new HelperSet();
+        try {
+            $helperset->get('foo');
+            $this->fail('->get() throws \InvalidArgumentException when helper not found');
+        } catch (\Exception $e) {
+            $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws \InvalidArgumentException when helper not found');
+            $this->assertContains('The helper "foo" is not defined.', $e->getMessage(), '->get() throws \InvalidArgumentException when helper not found');
+        }
+    }
+
+    /**
+     * @covers \Symfony\Component\Console\Helper\HelperSet::setCommand
+     */
+    public function testSetCommand()
+    {
+        $cmd_01 = new Command('foo');
+        $cmd_02 = new Command('bar');
+
+        $helperset = new HelperSet();
+        $helperset->setCommand($cmd_01);
+        $this->assertEquals($cmd_01, $helperset->getCommand(), '->setCommand() stores given command');
+
+        $helperset = new HelperSet();
+        $helperset->setCommand($cmd_01);
+        $helperset->setCommand($cmd_02);
+        $this->assertEquals($cmd_02, $helperset->getCommand(), '->setCommand() overwrites stored command with consecutive calls');
+    }
+
+    /**
+     * @covers \Symfony\Component\Console\Helper\HelperSet::getCommand
+     */
+    public function testGetCommand()
+    {
+        $cmd = new Command('foo');
+        $helperset = new HelperSet();
+        $helperset->setCommand($cmd);
+        $this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command');
+    }
+
+   /**
+     * Create a generic mock for the helper interface. Optionally check for a call to setHelperSet with a specific
+     * helperset instance.
+     *
+     * @param string    $name
+     * @param HelperSet $helperset allows a mock to verify a particular helperset set is being added to the Helper
+     */
+    private function getGenericMockHelper($name, HelperSet $helperset = null)
+    {
+        $mock_helper = $this->getMock('\Symfony\Component\Console\Helper\HelperInterface');
+        $mock_helper->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue($name));
+
+        if ($helperset) {
+            $mock_helper->expects($this->any())
+                ->method('setHelperSet')
+                ->with($this->equalTo($helperset));
+        }
+
+        return $mock_helper;
+    }
+}

+ 12 - 0
vendor/igorw/config-service-provider/.travis.yml

@@ -0,0 +1,12 @@
+language: php
+
+php:
+  - 5.3.3
+  - 5.3
+  - 5.4
+
+before_script:
+  - composer self-update
+  - composer install --dev --prefer-source
+
+script: phpunit --coverage-text

+ 42 - 0
vendor/igorw/config-service-provider/CHANGELOG.md

@@ -0,0 +1,42 @@
+CHANGELOG
+=========
+
+* 1.2.1 (2013-05-31)
+
+  * Deps: Support for 1.1 branch of silex
+
+* 1.2.0 (2013-04-23)
+
+  * BC break: Re-organized things into drivers
+  * Feature: Support for TOML format (@raphaelstolt)
+
+* 1.1.5 (2013-03-09)
+
+  * Bugfix: Allow recursive merging of empty hash values (@fzerorubigd)
+
+* 1.1.4 (2013-03-05)
+
+  * Feature: Throw exception on invalid JSON (@binfo)
+
+* 1.1.3 (2013-02-03)
+
+  * Feature: Recursive merging of config values (@airdeck)
+
+* 1.1.2 (2013-01-28)
+
+  * Feature: Support for plain-PHP config files
+
+* 1.1.1 (2013-01-03)
+
+  * Feature: Allow defining replacements in config file (@MarcinKleczek)
+  * Bugfix: Allow empty config file (@rsvasilyev)
+
+* 1.1.0 (2012-08-27)
+
+  * Feature: Optional YAML format support (@timheil)
+  * Bugfix: Only run strtr on string values to prevent implicit cast
+
+* 1.0.0 (2012-07-14)
+
+  * First tagged release
+  * Feature: Replacements (@jeromemacias)

+ 37 - 0
vendor/igorw/config-service-provider/src/Igorw/Silex/ChainConfigDriver.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Igorw\Silex;
+
+use Toml\Parser;
+
+class ChainConfigDriver implements ConfigDriver
+{
+    private $drivers;
+
+    public function __construct(array $drivers)
+    {
+        $this->drivers = $drivers;
+    }
+
+    public function load($filename)
+    {
+        $driver = $this->getDriver($filename);
+        return $driver->load($filename);
+    }
+
+    public function supports($filename)
+    {
+        return (bool) $this->getDriver($filename);
+    }
+
+    private function getDriver($filename)
+    {
+        foreach ($this->drivers as $driver) {
+            if ($driver->supports($filename)) {
+                return $driver;
+            }
+        }
+
+        return null;
+    }
+}

+ 9 - 0
vendor/igorw/config-service-provider/src/Igorw/Silex/ConfigDriver.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace Igorw\Silex;
+
+interface ConfigDriver
+{
+    function load($filename);
+    function supports($filename);
+}

+ 43 - 0
vendor/igorw/config-service-provider/src/Igorw/Silex/JsonConfigDriver.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace Igorw\Silex;
+
+class JsonConfigDriver implements ConfigDriver
+{
+    public function load($filename)
+    {
+        $config = $this->parseJson($filename);
+
+        if (JSON_ERROR_NONE !== json_last_error()) {
+            $jsonError = $this->getJsonError(json_last_error());
+            throw new \RuntimeException(
+                sprintf('Invalid JSON provided "%s" in "%s"', $jsonError, $filename));
+        }
+
+        return $config ?: array();
+    }
+
+    public function supports($filename)
+    {
+        return (bool) preg_match('#\.json(\.dist)?$#', $filename);
+    }
+
+    private function parseJson($filename)
+    {
+        $json = file_get_contents($filename);
+        return json_decode($json, true);
+    }
+
+    private function getJsonError($code)
+    {
+        $errorMessages = array(
+            JSON_ERROR_DEPTH            => 'The maximum stack depth has been exceeded',
+            JSON_ERROR_STATE_MISMATCH   => 'Invalid or malformed JSON',
+            JSON_ERROR_CTRL_CHAR        => 'Control character error, possibly incorrectly encoded',
+            JSON_ERROR_SYNTAX           => 'Syntax error',
+            JSON_ERROR_UTF8             => 'Malformed UTF-8 characters, possibly incorrectly encoded',
+        );
+
+        return isset($errorMessages[$code]) ? $errorMessages[$code] : 'Unknown';
+    }
+}

+ 18 - 0
vendor/igorw/config-service-provider/src/Igorw/Silex/PhpConfigDriver.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Igorw\Silex;
+
+class PhpConfigDriver implements ConfigDriver
+{
+    public function load($filename)
+    {
+        $config = require $filename;
+        $config = (1 === $config) ? array() : $config;
+        return $config ?: array();
+    }
+
+    public function supports($filename)
+    {
+        return (bool) preg_match('#\.php(\.dist)?$#', $filename);
+    }
+}

+ 23 - 0
vendor/igorw/config-service-provider/src/Igorw/Silex/TomlConfigDriver.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace Igorw\Silex;
+
+use Toml\Parser;
+
+class TomlConfigDriver implements ConfigDriver
+{
+    public function load($filename)
+    {
+        if (!class_exists('Toml\\Parser')) {
+            throw new \RuntimeException('Unable to read toml as the Toml Parser is not installed.');
+        }
+
+        $config = Parser::fromFile($filename);
+        return $config ?: array();
+    }
+
+    public function supports($filename)
+    {
+        return (bool) preg_match('#\.toml(\.dist)?$#', $filename);
+    }
+}

+ 22 - 0
vendor/igorw/config-service-provider/src/Igorw/Silex/YamlConfigDriver.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Igorw\Silex;
+
+use Symfony\Component\Yaml\Yaml;
+
+class YamlConfigDriver implements ConfigDriver
+{
+    public function load($filename)
+    {
+        if (!class_exists('Symfony\\Component\\Yaml\\Yaml')) {
+            throw new \RuntimeException('Unable to read yaml as the Symfony Yaml Component is not installed.');
+        }
+        $config = Yaml::parse($filename);
+        return $config ?: array();
+    }
+
+    public function supports($filename)
+    {
+        return (bool) preg_match('#\.ya?ml(\.dist)?$#', $filename);
+    }
+}

+ 204 - 0
vendor/igorw/config-service-provider/tests/integration/ConfigServiceProviderTest.php

@@ -0,0 +1,204 @@
+<?php
+
+/*
+ * This file is part of ConfigServiceProvider.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Silex\Application;
+use Igorw\Silex\ConfigServiceProvider;
+
+/**
+ * @author Igor Wiedler <igor@wiedler.ch>
+ * @author Jérôme Macias <jerome.macias@gmail.com>
+ */
+class ConfigServiceProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider provideFilenames
+     */
+    public function testRegisterWithoutReplacement($filename)
+    {
+        $app = new Application();
+
+        $app->register(new ConfigServiceProvider($filename));
+
+        $this->assertSame(true, $app['debug']);
+        $this->assertSame('%data%', $app['data']);
+    }
+
+    /**
+     * @dataProvider provideFilenames
+     */
+    public function testRegisterWithReplacement($filename)
+    {
+        $app = new Application();
+
+        $app->register(new ConfigServiceProvider($filename, array(
+            'data' => 'test-replacement'
+        )));
+
+        $this->assertSame(true, $app['debug']);
+        $this->assertSame('test-replacement', $app['data']);
+    }
+
+    /**
+     * @dataProvider provideEmptyFilenames
+     */
+    public function testEmptyConfigs($filename)
+    {
+        $readConfigMethod = new \ReflectionMethod('Igorw\Silex\ConfigServiceProvider', 'readConfig');
+        $readConfigMethod->setAccessible(true);
+
+        $this->assertEquals(
+            array(),
+            $readConfigMethod->invoke(new ConfigServiceProvider($filename))
+        );
+    }
+
+    /**
+     * @dataProvider provideReplacementFilenames
+     */
+    public function testInFileReplacements($filename)
+    {
+        $app = new Application();
+
+        $app->register(new ConfigServiceProvider($filename));
+
+        $this->assertSame('/var/www', $app['%path%']);
+        $this->assertSame('/var/www/web/images', $app['path.images']);
+        $this->assertSame('/var/www/upload', $app['path.upload']);
+        $this->assertSame('http://example.com', $app['%url%']);
+        $this->assertSame('http://example.com/images', $app['url.images']);
+    }
+    /**
+     * Currently not tested via testMergeConfigs as TOML seems to have problems
+     * to create 'db.options' keys
+     */
+    public function testTomlMergeConfigs()
+    {
+        $app = new Application();
+
+        $filenameBase = __DIR__."/Fixtures/config_base.toml";
+        $filenameExtended = __DIR__."/Fixtures/config_extend.toml";
+
+        $app->register(new ConfigServiceProvider($filenameBase));
+        $app->register(new ConfigServiceProvider($filenameExtended));
+
+        $this->assertSame('pdo_mysql', $app['db']['driver']);
+        $this->assertSame('utf8', $app['db']['charset']);
+        $this->assertSame('127.0.0.1', $app['db']['host']);
+        $this->assertSame('mydatabase', $app['db']['dbname']);
+        $this->assertSame('root', $app['db']['user']);
+        $this->assertSame('', $app['db']['password']);
+
+        $this->assertSame('123', $app['myproject']['param1']);
+        $this->assertSame('456', $app['myproject']['param2']);
+        $this->assertSame('456', $app['myproject']['param3']);
+        $this->assertSame(array(4, 5, 6), $app['myproject']['param4']);
+        $this->assertSame('456', $app['myproject']['param5']);
+
+        $this->assertSame(array(1, 2, 3, 4), $app['keys']['set']);
+    }
+
+    /**
+     * @dataProvider provideMergeFilenames
+     */
+    public function testMergeConfigs($filenameBase, $filenameExtended)
+    {
+        $app = new Application();
+        $app->register(new ConfigServiceProvider($filenameBase));
+        $app->register(new ConfigServiceProvider($filenameExtended));
+
+        $this->assertSame('pdo_mysql', $app['db.options']['driver']);
+        $this->assertSame('utf8', $app['db.options']['charset']);
+        $this->assertSame('127.0.0.1', $app['db.options']['host']);
+        $this->assertSame('mydatabase', $app['db.options']['dbname']);
+        $this->assertSame('root', $app['db.options']['user']);
+        $this->assertSame(null, $app['db.options']['password']);
+
+        $this->assertSame('123', $app['myproject.test']['param1']);
+        $this->assertSame('456', $app['myproject.test']['param2']);
+        $this->assertSame('123', $app['myproject.test']['param3']['param2A']);
+        $this->assertSame('456', $app['myproject.test']['param3']['param2B']);
+        $this->assertSame('456', $app['myproject.test']['param3']['param2C']);
+        $this->assertSame(array(4, 5, 6), $app['myproject.test']['param4']);
+        $this->assertSame('456', $app['myproject.test']['param5']);
+
+        $this->assertSame(array(1,2,3,4), $app['test.noparent.key']['test']);
+    }
+
+    /**
+     * @test
+     * @expectedException RuntimeException
+     * @expectedExceptionMessage Invalid JSON provided "Syntax error" in
+     */
+    public function invalidJsonShouldThrowException()
+    {
+        $app = new Application();
+        $app->register(new ConfigServiceProvider(__DIR__."/Fixtures/broken.json"));
+    }
+
+    /**
+     * @test
+     * @expectedException Symfony\Component\Yaml\Exception\ParseException
+     */
+    public function invalidYamlShouldThrowException()
+    {
+        $app = new Application();
+        $app->register(new ConfigServiceProvider(__DIR__."/Fixtures/broken.yml"));
+    }
+
+    /**
+     * @test
+     * @expectedException \Exception
+     */
+    public function invalidTomlShouldThrowException()
+    {
+        $app = new Application();
+        $app->register(new ConfigServiceProvider(__DIR__."/Fixtures/broken.toml"));
+    }
+
+    public function provideFilenames()
+    {
+        return array(
+            array(__DIR__."/Fixtures/config.php"),
+            array(__DIR__."/Fixtures/config.json"),
+            array(__DIR__."/Fixtures/config.yml"),
+            array(__DIR__."/Fixtures/config.toml"),
+        );
+    }
+
+    public function provideReplacementFilenames()
+    {
+        return array(
+            array(__DIR__."/Fixtures/config_replacement.php"),
+            array(__DIR__."/Fixtures/config_replacement.json"),
+            array(__DIR__."/Fixtures/config_replacement.yml"),
+            array(__DIR__."/Fixtures/config_replacement.toml"),
+        );
+    }
+
+    public function provideEmptyFilenames()
+    {
+        return array(
+            array(__DIR__."/Fixtures/config_empty.php"),
+            array(__DIR__."/Fixtures/config_empty.json"),
+            array(__DIR__."/Fixtures/config_empty.yml"),
+            array(__DIR__."/Fixtures/config_empty.toml"),
+        );
+    }
+
+    public function provideMergeFilenames()
+    {
+        return array(
+            array(__DIR__."/Fixtures/config_base.php", __DIR__."/Fixtures/config_extend.php"),
+            array(__DIR__."/Fixtures/config_base.json", __DIR__."/Fixtures/config_extend.json"),
+            array(__DIR__."/Fixtures/config_base.yml", __DIR__."/Fixtures/config_extend.yml"),
+        );
+    }
+}

Some files were not shown because too many files changed in this diff