diff --git a/app/Resources/views/Common/topbar.html.twig b/app/Resources/views/Common/topbar.html.twig new file mode 100644 index 0000000000..50d21abfc3 --- /dev/null +++ b/app/Resources/views/Common/topbar.html.twig @@ -0,0 +1,27 @@ +{% block topbar %} + +{% endblock %} diff --git a/app/Resources/views/Layouts/12.html.twig b/app/Resources/views/Layouts/12.html.twig new file mode 100644 index 0000000000..af3e503361 --- /dev/null +++ b/app/Resources/views/Layouts/12.html.twig @@ -0,0 +1,12 @@ +{% include '::Common/topbar.html.twig' %} +
+
+
+
+
+
+ {% block content %} + {% endblock %} +
+
+
diff --git a/app/Resources/views/Layouts/3-9.html.twig b/app/Resources/views/Layouts/3-9.html.twig new file mode 100644 index 0000000000..51a1b8f00a --- /dev/null +++ b/app/Resources/views/Layouts/3-9.html.twig @@ -0,0 +1,387 @@ +{% block header %} +
+ {% block logo %} + + {% endblock %} + + {% block nav %} + + {% endblock %} +
+{% endblock %} + {% block sonata_wrapper %} +
+ {% block sonata_left_side %} + + {% endblock sonata_left_side %} + +
+ + + + + {% endblock sonata_page_content %} + + + + {% endblock sonata_wrapper %} + diff --git a/app/Resources/views/Themes/page.html.twig b/app/Resources/views/Themes/page.html.twig new file mode 100644 index 0000000000..7224f44f86 --- /dev/null +++ b/app/Resources/views/Themes/page.html.twig @@ -0,0 +1,2 @@ +{% extends '::base.html.twig' %} +{% block theme 'page' %} diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig new file mode 100644 index 0000000000..0be119d426 --- /dev/null +++ b/app/Resources/views/base.html.twig @@ -0,0 +1,313 @@ +{% set _preview = block('preview') %} +{% set _form = block('form') %} +{% set _show = block('show') %} +{% set _list_table = block('list_table') %} +{% set _list_filters = block('list_filters') %} +{% set _tab_menu = block('tab_menu') %} +{% set _content = block('content') %} +{% set _title = block('title') %} +{% set _breadcrumb = block('breadcrumb') %} +{% set _actions = block('actions') %} +{% set _navbar_title = block('navbar_title') %} + + + + + + +{% block head %} + + + + + + + + + + {# Use the latest engine in ie8/ie9 or use google chrome engine if available #} + {# Improve usability in portal devices #} + + + {% block title %}{% endblock %} + + {% block stylesheets %} + + + + + + + {% endblock %} + + {% block javascripts %} + + + + {% endblock %} + + {% block header_end %}{% endblock header_end %} + + {% block extraHead %} + {% endblock %} +{% endblock %} + + + +{% block layout %}{% endblock %} + + diff --git a/app/Resources/views/layout.html.twig b/app/Resources/views/layout.html.twig new file mode 100644 index 0000000000..190a18037c --- /dev/null +++ b/app/Resources/views/layout.html.twig @@ -0,0 +1 @@ +123 diff --git a/app/config/config.yml b/app/config/config.yml index d9b0e76134..ca38793d2f 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -151,6 +151,7 @@ doctrine: json: Sonata\Doctrine\Types\JsonType #currency: Sonata\Component\Currency\CurrencyDoctrineType orm: + auto_generate_proxy_classes: "%kernel.debug%" default_entity_manager: default # auto_mapping: true diff --git a/cli-config.php b/cli-config.php new file mode 100644 index 0000000000..b647edceeb --- /dev/null +++ b/cli-config.php @@ -0,0 +1,32 @@ +setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache); + +use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Common\Annotations\AnnotationRegistry; + +$sysPath = __DIR__."/"; + +AnnotationRegistry::registerFile($sysPath."vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"); +$reader = new AnnotationReader(); + +$driverImpl = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, array($sysPath."tests/doctrine_console/mapping")); + +$config->setMetadataDriverImpl($driverImpl); +$config->setProxyDir(__DIR__ . '/Proxies'); +$config->setProxyNamespace('Proxies'); + +$defaultConnection = array( + 'driver' => 'pdo_mysql', + 'dbname' => 'chamilo', + 'user' => 'root', + 'password' => 'root', + 'host' => 'localhost', +); + + +$em = \Doctrine\ORM\EntityManager::create($defaultConnection, $config); + +use Doctrine\ORM\Tools\Console\ConsoleRunner; +return ConsoleRunner::createHelperSet($em); diff --git a/console-config.php b/console-config.php deleted file mode 100755 index 038a4277ab..0000000000 --- a/console-config.php +++ /dev/null @@ -1,183 +0,0 @@ -setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache); - -use Doctrine\Common\Annotations\AnnotationReader; -use Doctrine\Common\Annotations\AnnotationRegistry; - -$sysPath = __DIR__."/"; - -AnnotationRegistry::registerFile($sysPath."vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"); -$reader = new AnnotationReader(); - -$driverImpl = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, array($sysPath."tests/doctrine_console/mapping")); - -$config->setMetadataDriverImpl($driverImpl); -$config->setProxyDir(__DIR__ . '/Proxies'); -$config->setProxyNamespace('Proxies'); - -$courseList = CourseManager::get_real_course_list(); - -$app['chamilo.log'] = $app['sys_log_path'].'chamilo-cli.log'; - -// Loading db connections - -$connectionOptions = array(); - -if (!empty($courseList)) { - - $dbPrefix = isset($_configuration['db_prefix']) && !empty($_configuration['db_prefix']) ? $_configuration['db_prefix'].Database::get_database_glue() : null; - foreach ($courseList as $course) { - $connectionOptions['_chamilo_course_'.$course['db_name']] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $dbPrefix.$course['db_name'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], - ); - } -} - -if (isset($_configuration['main_database'])) { - $connectionOptions['main_database'] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['main_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], - ); -} - -if (isset($_configuration['statistics_database'])) { - $connectionOptions['statistics_database'] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['statistics_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], - ); -} else { - if (isset($_configuration['main_database'])) { - $connectionOptions['statistics_database'] = $connectionOptions['main_database']; - } -} - -if (isset($_configuration['user_personal_database'])) { - $connectionOptions['user_personal_database'] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['user_personal_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], - ); -} else { - if (isset($_configuration['main_database'])) { - $connectionOptions['user_personal_database'] = $connectionOptions['main_database']; - } -} - -$defaultConnection = array( - 'driver' => 'pdo_mysql' -); - -if (isset($_configuration['main_database'])) { - $defaultConnection = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['main_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], - ); -} - -$em = \Doctrine\ORM\EntityManager::create($defaultConnection, $config); - -//Fixes some errors -$platform = $em->getConnection()->getDatabasePlatform(); -$platform->registerDoctrineTypeMapping('enum', 'string'); -$platform->registerDoctrineTypeMapping('set', 'string'); - -$helpers = array( - 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()), - 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em), - 'configuration' => new \Chash\Helpers\ConfigurationHelper() -); - -use Doctrine\DBAL\DriverManager; -$multipleEM = array(); -foreach ($connectionOptions as $name => $connection) { - $em = \Doctrine\ORM\EntityManager::create($connection, $config); - //$helpers[$name] = new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em); - $helpers[$name] = new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()); -} - -/* -To generate doctrine2 entities you must: - -cd /var/www/chamilo11/tests/doctrine_console - -Delete old mappings/entities - -sudo rm -R mapping generated repository - -Creating the mapping from the DB - -sudo mkdir mapping generated repository - -You can add a Namespace if you want to with: --namespace "Entity" -sudo php5 doctrine.php orm:convert-mapping --force --from-database --namespace "Entity" annotation mapping - - -1. Generate entities - -sudo php5 doctrine.php orm:generate-entities --generate-annotations="true" generated - -Validate schema -sudo php5 doctrine.php orm:validate-schema -v - -Move generated files in a chamilo folder: - -sudo rm -R main/inc/Entity/* -mkdir main/inc/Entity - -cp -R tests/doctrine_console/generated/* main/inc/Entity - -fixes \ORM bug see http://redgreenrefactor.blogsite.org/php/code-first-approaching-php-with-doctrine-2-2-1-and-composer/ -cd main/inc/Entity - -sed -i 's/@ORM\\/@/g' *.php - -For tests -php5 tests/doctrine_console/doctrine.php orm:generate-entities --generate-annotations="true" main/inc/Entity - -Then autoload classes with composer -sudo php5 composer.phar update or sudo composer.phar update - -2. Migrations - -a. Generate empty migration file -cd /var/www/chamilo11/tests/doctrine_console - -php5 doctrine.php migrations:generate - -b. Check status - -php5 doctrine.php migrations:status - -c. Check sql -php5 doctrine.php migrations:migrate --dry-run - -d. execute migration -php5 doctrine.php migrations:migrate - -e. Revert migrations -php5 doctrine.php migrations:migrate 0 - - -http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/reference/managing_migrations.html - -*/ - diff --git a/console.php b/console.php deleted file mode 100755 index 05b6d00b6b..0000000000 --- a/console.php +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env php -register( - new ConsoleServiceProvider(), - array( - 'console.name' => 'Chamilo CLI', - 'console.version' => '1.0.0', - 'console.project_directory' => __DIR__.'/..' - ) -); - - -// Variable $helperSet is defined inside cli-config.php -//require __DIR__.'/console-config.php'; -//$cli = new \Symfony\Component\Console\Application('Chamilo CLI'); - -// Adding commands. -/** @var Knp\Console\Application $cli */ -$cli = $app['console']; - -$cli->setCatchExceptions(true); - -$helpers = array( - 'configuration' => new Chash\Helpers\ConfigurationHelper() -); -$helperSet = $cli->getHelperSet(); -foreach ($helpers as $name => $helper) { - $helperSet->set($helper, $name); -} - -$cli->addCommands( - array( - // DBAL Commands. - new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(), - new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(), - - // ORM Commands. - new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(), - new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(), - new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(), - new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(), - new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(), - new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(), - new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(), - new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(), - new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(), - new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(), - new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(), - new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(), - new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(), - new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(), - - // Migrations Commands. - new \Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand(), - new \Doctrine\DBAL\Migrations\Tools\Console\Command\ExecuteCommand(), - new \Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand(), - new \Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand(), - new \Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand(), - new \Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand(), - - // Chamilo commands. - - new ChamiloLMS\Command\Template\AsseticDumpCommand(), - new ChamiloLMS\Command\Translation\ExportLanguagesCommand(), - - // Chash commands. - new Chash\Command\Database\RunSQLCommand(), - //new Chash\Command\Database\DumpCommand(), - //new Chash\Command\Database\RestoreCommand(), - new Chash\Command\Database\SQLCountCommand(), - new Chash\Command\Database\FullBackupCommand(), - //new Chash\Command\Database\DropDatabaseCommand(), - - new Chash\Command\Files\CleanTempFolderCommand(), - - new Chash\Command\Translation\ExportLanguageCommand(), - new Chash\Command\Translation\ImportLanguageCommand() - ) -); -$cli->run(); diff --git a/index.php b/index.php deleted file mode 100644 index 4a653353fd..0000000000 --- a/index.php +++ /dev/null @@ -1,7 +0,0 @@ - -$htmlHeadXtra[] = to_javascript(); -$htmlHeadXtra[] = user_group_filter_javascript(); +function plus_repeated_event() { + if (document.getElementById('options2').style.display == 'none') { + document.getElementById('options2').style.display = 'block'; + } else { + document.getElementById('options2').style.display = 'none'; + } +} + $(function() { + var checked = $('input[name=repeat]').attr('checked'); + if (checked) { + $('#options2').show(); + } + }); + +"; // setting the name of the tool -$nameTools = get_lang('Agenda'); // language variable in trad4all.inc.php -// showing the header if we are not in the learning path, if we are in -// the learning path, we do not include the banner so we have to explicitly -// include the stylesheet, which is normally done in the header -if (!empty($group_id)) { - $group_properties = GroupManager :: get_group_properties($group_id); - $interbreadcrumb[] = array("url" => "../group/group.php", "name" => get_lang('Groups')); - $interbreadcrumb[] = array( - "url" => "../group/group_space.php?gidReq=".$group_id, - "name" => get_lang('GroupSpace').' '.$group_properties['name'] - ); - Display::display_header($nameTools, 'Agenda'); -} elseif (empty($origin) or $origin != 'learnpath') { - Display::display_header($nameTools, 'Agenda'); -} +$nameTools = get_lang('Agenda'); -/* - TRACKING - */ event_access_tool(TOOL_CALENDAR_EVENT); -/* SETTING SOME VARIABLES - */ -// Variable definitions -// Defining the shorts for the days. We use camelcase because these are arrays of language variables -$DaysShort = api_get_week_days_short(); -// Defining the days of the week to allow translation of the days. We use camelcase because these are arrays of language variables -$DaysLong = api_get_week_days_long(); -// Defining the months of the year to allow translation of the months. We use camelcase because these are arrays of language variables -$MonthsLong = api_get_months_long(); - -// Database table definitions -$TABLEAGENDA = Database::get_course_table(TABLE_AGENDA); -$TABLE_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY); -$tbl_user = Database::get_main_table(TABLE_MAIN_USER); -$tbl_courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER); -$tbl_group = Database::get_course_table(TABLE_GROUP); -$tbl_groupUser = Database::get_course_table(TABLE_GROUP_USER); - -/* ACCESS RIGHTS */ // permission stuff - also used by loading from global in agenda.inc.php -$is_allowed_to_edit = api_is_allowed_to_edit(false, true) OR (api_get_course_setting( - 'allow_user_edit_agenda' -) && !api_is_anonymous()); - -// Tool introduction -Display::display_introduction_section(TOOL_CALENDAR_EVENT); - -/* MAIN SECTION */ - -//setting the default year and month -$select_year = ''; -$select_month = ''; -$select_day = ''; - -if (!empty($_GET['year'])) { - $select_year = (int)$_GET['year']; -} -if (!empty($_GET['month'])) { - $select_month = (int)$_GET['month']; -} -if (!empty($_GET['day'])) { - $select_day = (int)$_GET['day']; -} - -$today = getdate(); - -if (empty($select_year)) { - $select_year = $today['year']; -} -if (empty($select_month)) { - $select_month = $today['mon']; -} - -echo '
'; - -if (api_is_allowed_to_edit(false, true) OR - (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) && api_is_allowed_to_session_edit( - false, - true - ) OR - GroupManager::user_has_access( - api_get_user_id(), - $group_id, - GroupManager::GROUP_TOOL_CALENDAR - ) && GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) -) { - echo display_courseadmin_links(); -} - -echo '
'; - -$event_id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null; -$type = $event_type = isset($_GET['type']) ? $_GET['type'] : null; +$is_allowed_to_edit = api_is_allowed_to_edit(false, true) OR (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()); +$agenda = new Agenda(); +$agenda->type = $type; +$actions = $agenda->displayActions('calendar'); if ($type == 'fromjs') { - $id_list = explode('_', $event_id); - $event_id = $id_list[1]; + $id_list = explode('_', $eventId); + $eventId = $id_list[1]; $event_type = $id_list[0]; } if (!api_is_allowed_to_edit(null, true) && $event_type == 'course') { - api_not_allowed(); + api_not_allowed(true); +} +if ($event_type == 'course') { + $agendaUrl = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?'.api_get_cidreq().'&type=course'; +} else { + $agendaUrl = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?&type='.$event_type; } - $course_info = api_get_course_info(); +$agenda->type = $event_type; + +$message = null; +$content = null; -if (api_is_allowed_to_edit(false, true) or - ( - api_get_course_setting('allow_user_edit_agenda') && - !api_is_anonymous() && - api_is_allowed_to_session_edit(false, true) - ) or - GroupManager::user_has_access(api_get_user_id(), $group_id, GroupManager::GROUP_TOOL_CALENDAR) && +if (api_is_allowed_to_edit(false, true) OR + (api_get_course_setting('allow_user_edit_agenda') && + !api_is_anonymous() && + api_is_allowed_to_session_edit(false, true)) OR + GroupManager::user_has_access(api_get_user_id(), $group_id, GroupManager::GROUP_TOOL_CALENDAR) && GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) ) { switch ($action) { case 'add': - if (isset($_POST['submit_event']) && $_POST['submit_event']) { + $actionName = get_lang('Add'); + $form = $agenda->getForm(array('action' => 'add')); - $startDate = Text::return_datetime_from_array($_POST['start_date']); - $endDate = Text::return_datetime_from_array($_POST['end_date']); - $repeatEndDay = Text::return_datetime_from_array($_POST['repeat_end_day']); + if ($form->validate()) { + $values = $form->getSubmitValues(); - $fileComment = isset($_POST['file_comment']) ? $_POST['file_comment'] : null; - $fileAttachment = isset($_FILES['user_upload']) ? $_FILES['user_upload'] : null; - $agenda = new Agenda(); - $agenda->setType('course'); + $sendEmail = isset($values['add_announcement']) ? true : false; + $allDay = isset($values['all_day']) ? 'true' : 'false'; - $repeatSettings = array(); + $sendAttachment = isset($_FILES['user_upload']) ? true : false; + $attachment = $sendAttachment ? $_FILES['user_upload'] : null; + $attachmentComment = isset($values['file_comment']) ? $values['file_comment'] : null; - if (!empty($_POST['repeat'])) { - $repeatSettings = array( - 'repeat_type' => $_POST['repeat_type'], - 'repeat_end' => $repeatEndDay - ); - /* - $res = agenda_add_repeat_item( - $course_info, - $id, - $_POST['repeat_type'], - $repeatEndDay, - $_POST['users'], - $safe_file_comment - );*/ - } + $startDate = $values['date_range_start']; + $endDate = $values['date_range_end']; - $id = $agenda->add_event( + $eventId = $agenda->add_event( $startDate, $endDate, + $allDay, + $values['title'], + $values['content'], + $values['users_to_send'], + $sendEmail, null, - null, - $_POST['title'], - $_POST['content'], - $_POST['users'], - false, - null, - array('comment' => $fileComment, 'file' => $fileAttachment), - $repeatSettings + $attachment, + $attachmentComment ); - Display::display_confirmation_message(get_lang('AddSuccess')); + + if (!empty($values['repeat']) && !empty($eventId)) { + // End date is always set as 23:59:59 + $endDate = substr($values['repeat_end_day'], 0, 10).' 23:59:59'; + $agenda->addRepeatedItem( + $eventId, + $values['repeat_type'], + $endDate, + $values['users_to_send'] + ); + } + $message = Display::return_message(get_lang('AddSuccess'), 'confirmation'); + if ($sendEmail) { + $message .= Display::return_message(get_lang('AdditionalMailWasSentToSelectedUsers'), 'confirmation'); + } + Session::write('message', $message); + header("Location: $agendaUrl"); + exit; } else { - show_add_form(); + $content = $form->return_form(); } break; - case "announce": - //copying the agenda item into an announcement - if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $event_id))) { - // a coach can only delete an element belonging to his session - $ann_id = store_agenda_item_as_announcement($event_id); - $tool_group_link = (isset($_SESSION['toolgroup']) ? '&toolgroup='.$_SESSION['toolgroup'] : ''); - Display::display_normal_message( - get_lang( - 'CopiedAsAnnouncement' - ).' '.get_lang( - 'NewAnnouncement' - ).'', - false + case 'edit': + $actionName = get_lang('Edit'); + $event = $agenda->get_event($eventId); + + if (empty($event)) { + api_not_allowed(true); + } + + $event['action'] = 'edit'; + $event['id'] = $eventId; + + $form = $agenda->getForm($event); + + if ($form->validate()) { + $values = $form->getSubmitValues(); + + $allDay = isset($values['all_day']) ? 'true' : 'false'; + $startDate = $values['date_range_start']; + $endDate = $values['date_range_end']; + + $sendAttachment = isset($_FILES['user_upload']) ? true : false; + $attachment = $sendAttachment ? $_FILES['user_upload'] : null; + $attachmentComment = isset($values['file_comment']) ? $values['file_comment'] : null; + + // This is a sub event. Delete the current and create another BT#7803 + + if (!empty($event['parent_event_id'])) { + $agenda->delete_event($eventId); + + $eventId = $agenda->add_event( + $startDate, + $endDate, + $allDay, + $values['title'], + $values['content'], + $values['users_to_send'], + false, + null, + $attachment, + $attachmentComment + ); + + $message = Display::return_message(get_lang('Updated'), 'confirmation'); + Session::write('message', $message); + header("Location: $agendaUrl"); + exit; + } + + // Editing normal event. + + $agenda->edit_event( + $eventId, + $startDate, + $endDate, + $allDay, + $values['title'], + $values['content'], + $values['users_to_send'], + $attachment, + $attachmentComment ); + + if (!empty($values['repeat']) && !empty($eventId)) { + // End date is always set as 23:59:59 + $endDate = substr($values['repeat_end_day'], 0, 10).' 23:59:59'; + $agenda->addRepeatedItem( + $eventId, + $values['repeat_type'], + $endDate, + $values['users_to_send'] + ); + } + + $deleteAttachment = isset($values['delete_attachment']) ? true : false; + + if ($deleteAttachment && isset($event['attachment']) && !empty($event['attachment'])) { + $agenda->deleteAttachmentFile( + $event['attachment']['id'], + $agenda->course + ); + } + + $message = Display::return_message(get_lang('Updated'), 'confirmation'); + Session::write('message', $message); + header("Location: $agendaUrl"); + exit; + } else { + $content = $form->return_form(); + } break; case 'importical': - if (isset($_POST['ical_submit'])) { + $form = $agenda->getImportCalendarForm(); + $content = $form->return_form(); + + if ($form->validate()) { $ical_name = $_FILES['ical_import']['name']; $ical_type = $_FILES['ical_import']['type']; - $ext = substr($ical_name, (strrpos($ical_name, ".") + 1)); - //$ical_type === 'text/calendar' if ($ext === 'ics' || $ext === 'ical' || $ext === 'icalendar' || $ext === 'ifb') { - $agenda_result = agenda_import_ical($course_info, $_FILES['ical_import']); + $result = $agenda->importEventFile($course_info, $_FILES['ical_import']); $is_ical = true; } else { $is_ical = false; } if (!$is_ical) { - Display::display_error_message(get_lang('IsNotiCalFormatFile')); - display_ical_import_form(); + $message = Display::return_message(get_lang('IsNotiCalFormatFile'), 'error'); + $form = $agenda->getImportCalendarForm(); + $content = $form->return_form(); break; } else { - Display::display_confirmation_message(get_lang('AddSuccess')); - echo $agenda_result; + $message = Display::return_message(get_lang('AddSuccess'), 'error'); + $content = $result; } - } else { - display_ical_import_form(); - } - break; - case 'edit': - // a coach can only delete an element belonging to his session - if ($_POST['submit_event']) { - store_edited_agenda_item($event_id, $_REQUEST['id_attach'], $_REQUEST['file_comment']); - $action = 'view'; - } else { - show_add_form($event_id, $event_type); + Session::write('message', $message); } break; case "delete": - if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $event_id))) { + if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $eventId) )) { // a coach can only delete an element belonging to his session - delete_agenda_item($event_id); - $action = 'view'; - } - break; - case "showhide": - if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $event_id))) { - // a coach can only delete an element belonging to his session - showhide_agenda_item($event_id); - $action = 'view'; - } - if (!empty($_GET['agenda_id'])) { - display_one_agenda_item($_GET['agenda_id']); - } - break; - case "delete_attach": //delete attachment file - $id_attach = $_GET['id_attach']; - if (!empty($id_attach)) { - delete_attachment_file($id_attach); - $action = 'view'; + $content = $agenda->delete_event($eventId); } break; } } -// The footer is displayed only if we are not in the learnpath -if ($origin != 'learnpath') { - Display::display_footer(); +if (!empty($group_id)) { + $group_properties = GroupManager :: get_group_properties($group_id); + $interbreadcrumb[] = array( + "url" => api_get_path(WEB_CODE_PATH)."group/group.php", + "name" => get_lang('Groups') + ); + $interbreadcrumb[] = array( + "url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?gidReq=".$group_id, + "name" => get_lang('GroupSpace').' '.$group_properties['name'] + ); +} +if (!empty($actionName)) { + $interbreadcrumb[] = array( + "url" => $url, + "name" => get_lang('Agenda') + ); } + +// Tool introduction +$introduction = Display::return_introduction_section(TOOL_CALENDAR_EVENT); + +$message = Session::read('message'); +Session::erase('message'); + +$tpl = new Template($actionName); +$tpl->assign('content', $content); +$tpl->assign('actions', $actions); + +// Loading main Chamilo 1 col template +$tpl->display_one_col_template(); diff --git a/main/calendar/agenda_js.php b/main/calendar/agenda_js.php index 88e4c3fb5f..532d1ab0f2 100644 --- a/main/calendar/agenda_js.php +++ b/main/calendar/agenda_js.php @@ -8,9 +8,6 @@ */ use \ChamiloSession as Session; -// name of the language file that needs to be included -$language_file = array('agenda', 'group', 'announcements'); - // use anonymous mode when accessing this course tool $use_anonymous = true; @@ -23,7 +20,6 @@ if ($type == 'personal') { $cidReset = true; // fixes #5162 } -require_once '../inc/global.inc.php'; require_once 'agenda.inc.php'; $current_course_tool = TOOL_CALENDAR_EVENT; @@ -66,8 +62,8 @@ if (!empty($group_id)) { } $app['title'] = get_lang('Agenda'); -$tpl = $app['template']; -$tpl->assign('use_google_calendar', 0); +$tpl = Session::getTwig(); +$tpl->addGlobal('use_google_calendar', 0); $can_add_events = 0; @@ -97,8 +93,8 @@ switch($type) { } $extra_field_data = UserManager::get_extra_user_data_by_field(api_get_user_id(), 'google_calendar_url'); if (!empty($extra_field_data) && isset($extra_field_data['google_calendar_url']) && !empty($extra_field_data['google_calendar_url'])) { - $tpl->assign('use_google_calendar', 1); - $tpl->assign('google_calendar_url', $extra_field_data['google_calendar_url']); + $tpl->addGlobal('use_google_calendar', 1); + $tpl->addGlobal('google_calendar_url', $extra_field_data['google_calendar_url']); } $this_section = SECTION_MYAGENDA; if (!api_is_anonymous()) { @@ -115,52 +111,44 @@ $months = api_get_months_long(); $months_short = api_get_months_short(); //Setting calendar translations -$tpl->assign('month_names', json_encode($months)); -$tpl->assign('month_names_short', json_encode($months_short)); -$tpl->assign('day_names', json_encode($days)); -$tpl->assign('day_names_short', json_encode($day_short)); -$tpl->assign( - 'button_text', - json_encode( - array( +$tpl->addGlobal('month_names', json_encode($months)); +$tpl->addGlobal('month_names_short', json_encode($months_short)); +$tpl->addGlobal('day_names', json_encode($days)); +$tpl->addGlobal('day_names_short', json_encode($day_short)); +$tpl->addGlobal('button_text', + json_encode(array( 'today' => get_lang('Today'), 'month' => get_lang('Month'), 'week' => get_lang('Week'), 'day' => get_lang('Day') - ) - ) + )) ); //see http://docs.jquery.com/UI/Datepicker/$.datepicker.formatDate -$tpl->assign('js_format_date', 'D d M yy'); +$tpl->addGlobal('js_format_date', 'D d M yy'); $region_value = api_get_language_isocode(); if ($region_value == 'en') { $region_value = 'en-GB'; } -$tpl->assign('region_value', $region_value); -$tpl->assign('export_ical_confidential_icon', Display::return_icon('export.png', get_lang('ExportiCalConfidential'))); - -$actions = null; -$filter = null; -if (api_is_allowed_to_edit(false,true) OR - (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) && - api_is_allowed_to_session_edit(false,true) OR - $is_group_tutor -) { - if ($type == 'course') { - if (isset($_GET['user_id'])) { - $filter = $_GET['user_id']; - } - $actions = display_courseadmin_links($filter); - } - $tpl->assign('actions', $actions); -} +$tpl->addGlobal('region_value', $region_value); + +$export_icon = api_get_path(WEB_IMG_PATH).'img/export.png'; +$export_icon_low = api_get_path(WEB_IMG_PATH).'img/export_low_fade.png'; +$export_icon_high = api_get_path(WEB_IMG_PATH).'img/export_high_fade.png'; + +$tpl->addGlobal( + 'export_ical_confidential_icon', + Display::return_icon($export_icon_high, get_lang('ExportiCalConfidential')) +); -//Calendar Type : course, admin, personal -$tpl->assign('type', $type); +$actions = $agenda->displayActions('calendar', $userId); + $tpl->addGlobal('actions', $actions); + +// Calendar Type : course, admin, personal +$tpl->addGlobal('type', $type); $type_event_class = $type.'_event'; $type_label = get_lang(ucfirst($type).'Calendar'); @@ -169,89 +157,64 @@ if ($type == 'course' && !empty($group_id)) { $type_label = get_lang('GroupCalendar'); } +$defaultView = api_get_setting('default_calendar_view'); + +if (empty($defaultView)) { + $defaultView = 'month'; +} + +/* month, basicWeek, agendaWeek, agendaDay */ + +$tpl->addGlobal('default_view', $defaultView); if ($type == 'course' && !empty($session_id)) { $type_event_class = 'session_event'; $type_label = get_lang('SessionCalendar'); } -$tpl->assign('type_label', $type_label); -$tpl->assign('type_event_class', $type_event_class); +$tpl->addGlobal('type_label', $type_label); +$tpl->addGlobal('type_event_class', $type_event_class); -//Current user can add event? -$tpl->assign('can_add_events', $can_add_events); +// Current user can add event? +$tpl->addGlobal('can_add_events', $can_add_events); //Setting AJAX caller -if (isset($_GET['user_id'])) { - $user_id = $_GET['user_id']; - $agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?user_id='.$user_id.'&type='.$type; +if (!empty($userId)) { + $agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?user_id='.$userId.'&type='.$type; } else { $agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?type='.$type; } -$tpl->assign('web_agenda_ajax_url', $agenda_ajax_url); - -$course_code = api_get_course_id(); -$select = null; -if ((api_is_allowed_to_edit() || $is_group_tutor) && $course_code != '-1' && $type == 'course') { - $order = 'lastname'; - if (api_is_western_name_order()) { - $order = 'firstname'; - } - if (!empty($group_id)) { - $group_list = array($group_id => $group_properties); - $user_list = GroupManager::get_subscribed_users($group_id); - } else { - $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()); - } - - $agenda = new Agenda(); + $tpl->addGlobal('web_agenda_ajax_url', $agenda_ajax_url); + + $course_code = api_get_course_id(); + //This will fill the select called #users_to_send_id - $select = $agenda->construct_not_selected_select_form($group_list, $user_list, array()); - $tpl->assign('visible_to', $select); -} -$form = new FormValidator('form-simple', '', null); -$form->addElement('label', get_lang('Date'), ''); -$form->addElement('label', get_lang('Title'), '
'); -$form->addElement('label', get_lang('Description'), '
'); -$tpl->assign('form_simple', $form->return_form()); - -$form = new FormValidator('add_event_form', null, null); -if (!empty($select)) { - $form->addElement( - 'label', - get_lang('To'), - $select, - array('id' => 'visible_to_input', 'style' => 'display:none') - ); -} + $form = new FormValidator('form', 'get', null, null, array('id' => 'add_event_form')); + $form->addElement('html', '
'); -$form->addElement( - 'label', - get_lang('To'), - '
', - array('id' => 'visible_to_read_only', 'style' => 'display:none') -); + $sendTo = $agenda->parseAgendaFilter($userId); + $addOnlyItemsInSendTo = true; -$form->addElement('label', get_lang('Agenda'), '
'); -$form->addElement('label', get_lang('Date'), ''); -$form->addElement( - 'label', - get_lang('Title'), - '' -); -$form->addElement( - 'label', - get_lang('Description'), - ' - ' -); + if ($sendTo['everyone']) { + $addOnlyItemsInSendTo = false; + } + + $agenda->showToForm($form, $sendTo, array(), $addOnlyItemsInSendTo); + $form->addElement('html', '
'); + + $form->addElement('html', ''); -if ($type == 'course') { - $form->addElement('html', '
'); - $form->addElement('checkbox', 'add_as_annonuncement', array(null, null, get_lang('AddAsAnnouncement').' ('.get_lang('SendEmail').')')); + $form->addElement('label', get_lang('Agenda'), '
'); + $form->addElement('label', get_lang('Date'), ''); + $form->addElement('text', 'title', get_lang('Title'), array('id' => 'title')); + $form->addElement('textarea', 'content', get_lang('Description'), array('id' => 'content')); + if ($agenda->type == 'course') { + $form->addElement('html', ''); } -$tpl->assign('form_add', $form->return_form()); +$tpl->addGlobal('form_add', $form->return_form()); +$tpl->render('ChamiloLMSCoreBundle:Calendar:month.html.twig'); -$tpl->display('default/agenda/month.tpl'); diff --git a/main/course_home/activity.php b/main/course_home/activity.php deleted file mode 100644 index b52ac7b00c..0000000000 --- a/main/course_home/activity.php +++ /dev/null @@ -1,80 +0,0 @@ - -

'.$title.'

-
- '.$content.''; - return $html; -} - -$session_id = api_get_session_id(); - -$urlGenerator = Session::$urlGenerator; - -$content = null; - -// Start of tools for CourseAdmins (teachers/tutors) -$totalList = array(); - -if ($session_id == 0 && api_is_course_admin() && api_is_allowed_to_edit(null, true)) { - $list = CourseHome::get_tools_category(TOOL_AUTHORING); - - $result = CourseHome::show_tools_category($urlGenerator, $list); - - $content .= return_block(get_lang('Authoring'), $result['content']); - - $totalList = $result['tool_list']; - - $list = CourseHome::get_tools_category(TOOL_INTERACTION); - $list2 = CourseHome::get_tools_category(TOOL_COURSE_PLUGIN); - $list = array_merge($list, $list2); - $result = CourseHome::show_tools_category($urlGenerator, $list); - $totalList = array_merge($totalList, $result['tool_list']); - - $content .= return_block(get_lang('Interaction'), $result['content']); - - $list = CourseHome::get_tools_category(TOOL_ADMIN_PLATFORM); - $totalList = array_merge($totalList, $list); - $result = CourseHome::show_tools_category($urlGenerator, $list); - - $totalList = array_merge($totalList, $result['tool_list']); - - $content .= return_block(get_lang('Administration'), $result['content']); - -} elseif (api_is_coach()) { - - $content .= '
'; - $list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW); - $content .= CourseHome::show_tools_category($urlGenerator, $result['content']); - $totalList = array_merge($totalList, $result['tool_list']); - $content .= '
'; -} else { - $list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW); - if (count($list) > 0) { - $content .= '
'; - $result = CourseHome::show_tools_category($urlGenerator, $list); - $content .= $result['content']; - $totalList = array_merge($totalList, $result['tool_list']); - $content .= '
'; - } -} - -return array( - 'content' => $content, - 'tool_list' => $totalList -); diff --git a/main/inc/lib/agenda.lib.php b/main/inc/lib/agenda.lib.php index e7b1b86a84..83d8c80037 100644 --- a/main/inc/lib/agenda.lib.php +++ b/main/inc/lib/agenda.lib.php @@ -2,160 +2,160 @@ /* For licensing terms, see /license.txt */ /** - * @author: Julio Montoya * Class Agenda - * @todo move this in main/inc/lib and update composer autoload + * + * @author: Julio Montoya */ + class Agenda { public $events = array(); - /** - * personal, admin or course - * @var string - */ + /** @var string Current type */ public $type = 'personal'; + public $types = array('personal', 'admin', 'course'); + public $sessionId = 0; + /** @var array */ + public $course; /** * */ public function __construct() { - // Table definitions - $this->tbl_global_agenda = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR); + //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); + $this->tbl_course_agenda = Database::get_course_table(TABLE_AGENDA); + $this->table_repeat = Database::get_course_table(TABLE_AGENDA_REPEAT); - // Setting the course object if we are in a course + //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; + $courseInfo = api_get_course_info(); + if (!empty($courseInfo)) { + $this->course = $courseInfo; } - + $this->sessionId = api_get_session_id(); $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_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 + * @param array $courseInfo */ - public function setType($type) + public function set_course($courseInfo) { - $this->type = $type; + $this->course = $courseInfo; } /** - * Sets course info - * @param array $course_info + * @return array */ - public function set_course($course_info) + public function getTypes() { - $this->course = $course_info; + return $this->types; } /** - * * 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 $allDay (true, false) + * @param string $title + * @param string $content + * @param array $usersToSend array('everyone') or a list of user/group ids + * @param bool $addAsAnnouncement event as a *course* announcement + * @param int $parentEventId + * @param array $attachmentArray $_FILES[''] + * @param string $attachmentComment * - * @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 - * @param int $parentId - * @param array $attachmentSettings - * @param array $repeatSettings - * @return bool - * + * @return int */ public function add_event( $start, $end, - $all_day, - $view, + $allDay, $title, $content, - $users_to_send = array(), - $add_as_announcement = false, - $parentId = null, - $attachmentSettings = array(), - $repeatSettings = array() + $usersToSend = array(), + $addAsAnnouncement = false, + $parentEventId = null, + $attachmentArray = array(), + $attachmentComment = null ) { - $start = api_get_utc_datetime($start); - $end = api_get_utc_datetime($end); - $all_day = isset($all_day) && $all_day == 'true' ? 1 : 0; + $start = api_get_utc_datetime($start); + $end = api_get_utc_datetime($end); + $allDay = isset($allDay) && $allDay == '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); + $attributes = array( + 'user' => api_get_user_id(), + 'title' => $title, + 'text' => $content, + 'date' => $start, + 'enddate' => $end, + 'all_day' => $allDay + ); + $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']; - $attributes['parent_event_id'] = $parentId; - - // Simple course event - $id = Database::insert($this->tbl_course_agenda, $attributes); + $attributes = array( + 'title' => $title, + 'content' => $content, + 'start_date' => $start, + 'end_date' => $end, + 'all_day' => $allDay, + 'session_id' => api_get_session_id(), + 'c_id' => $this->course['real_id'] + ); - if ($id) { + if (!empty($parentEventId)) { + $attributes['parent_event_id'] = $parentEventId; + } - if (!empty($attachmentSettings)) { - self::addAttachment($id, $attachmentSettings); - } + // Simple course event. + $id = Database::insert($this->tbl_course_agenda, $attributes); - if (!empty($repeatSettings)) { - $this->addRepeatItem( - $this->course, - $id, - $repeatSettings['repeat_type'], - $repeatSettings['repeat_end'], - $users_to_send - ); - } + if ($id) { + $groupId = api_get_group_id(); - $group_id = api_get_group_id(); + if (!empty($usersToSend)) { + $sendTo = $this->parseSendToArray($usersToSend); - 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']) { + if ($sendTo['everyone']) { api_item_property_update( $this->course, TOOL_CALENDAR_EVENT, $id, "AgendaAdded", api_get_user_id(), - $group_id, + $groupId, + '', + $start, + $end + ); + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "visible", + api_get_user_id(), + $groupId, '', $start, $end ); } else { - // storing the selected groups - if (isset($send_to['groups']) && is_array($send_to['groups'])) { - foreach ($send_to['groups'] as $group) { + // Storing the selected groups + if (!empty($sendTo['groups'])) { + foreach ($sendTo['groups'] as $group) { api_item_property_update( $this->course, TOOL_CALENDAR_EVENT, @@ -167,20 +167,44 @@ class Agenda $start, $end ); + + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "visible", + 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) { + if (!empty($sendTo['users'])) { + foreach ($sendTo['users'] as $userId) { api_item_property_update( $this->course, TOOL_CALENDAR_EVENT, $id, "AgendaAdded", api_get_user_id(), - $group_id, - $to_user_id, + $groupId, + $userId, + $start, + $end + ); + + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "visible", + api_get_user_id(), + $groupId, + $userId, $start, $end ); @@ -189,20 +213,34 @@ class Agenda } } - if (isset($add_as_announcement) && !empty($add_as_announcement)) { - self::store_agenda_item_as_announcement($id, $users_to_send); + // Add announcement. + if ($addAsAnnouncement) { + $this->store_agenda_item_as_announcement($id, $usersToSend); + } + + // Add attachment. + if (isset($attachmentArray) && !empty($attachmentArray)) { + $this->addAttachment( + $id, + $attachmentArray, + $attachmentComment, + $this->course + ); } } 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); + $attributes = array( + 'title' => $title, + 'content' => $content, + 'start_date' => $start, + 'end_date' => $end, + 'all_day' => $allDay, + 'access_url_id' => api_get_current_access_url_id() + ); + + $id = Database::insert($this->tbl_global_agenda, $attributes); } break; } @@ -210,70 +248,253 @@ class Agenda return $id; } + /** + * @param int $eventId + * @param int $courseId + * + * @return array + */ + public function getRepeatedInfoByEvent($eventId, $courseId) + { + $repeatTable = Database::get_course_table(TABLE_AGENDA_REPEAT); + $eventId = intval($eventId); + $courseId = intval($courseId); + $sql = "SELECT * FROM $repeatTable + WHERE c_id = $courseId AND cal_id = $eventId"; + $res = Database::query($sql); + $repeatInfo = array(); + if (Database::num_rows($res) > 0) { + $repeatInfo = Database::fetch_array($res, 'ASSOC'); + } + + return $repeatInfo; + } /** - * @param int id - * @param array sent to - **/ + * @param int $eventId + * @param string $type + * @param string $end in local time + * @param array $sentTo + * + * @return bool + */ + public function addRepeatedItem($eventId, $type, $end, $sentTo = array()) + { + $t_agenda = Database::get_course_table(TABLE_AGENDA); + $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT); + + if (empty($this->course)) { + return false; + } + + $course_id = $this->course['real_id']; + $eventId = intval($eventId); + + $sql = "SELECT title, content, start_date, end_date, all_day + FROM $t_agenda + WHERE c_id = $course_id AND id = $eventId"; + $res = Database::query($sql); + + if (Database::num_rows($res) !== 1) { + return false; + } + + $row = Database::fetch_array($res); + $origStartDate = api_strtotime($row['start_date'], 'UTC'); + $origEndDate = api_strtotime($row['end_date'], 'UTC'); + $diff = $origEndDate - $origStartDate; + + $title = $row['title']; + $content = $row['content']; + $allDay = $row['all_day']; + + $now = time(); + $type = Database::escape_string($type); + $end = api_strtotime($end); + + if (1 <= $end && $end <= 500) { + // We assume that, with this type of value, the user actually gives a count of repetitions + //and that he wants us to calculate the end date with that (particularly in case of imports from ical) + switch ($type) { + case 'daily': + $end = $origStartDate + (86400 * $end); + break; + case 'weekly': + $end = $this->addWeek($origStartDate, $end); + break; + case 'monthlyByDate': + $end = $this->addMonth($origStartDate, $end); + break; + case 'monthlyByDay': + //TODO + break; + case 'monthlyByDayR': + //TODO + break; + case 'yearly': + $end = $this->addYear($origStartDate, $end); + break; + } + } + + $typeList = array('daily', 'weekly', 'monthlyByDate', 'monthlyByDay', 'monthlyByDayR', 'yearly'); + + if ($end > $now && in_array($type, $typeList)) { + $sql = "INSERT INTO $t_agenda_r (c_id, cal_id, cal_type, cal_end) + VALUES ($course_id, '$eventId', '$type', '$end')"; + Database::query($sql); + + switch ($type) { + // @todo improve loop. + case 'daily': + for ($i = $origStartDate + 86400; $i <= $end; $i += 86400) { + $start = date('Y-m-d H:i:s', $i); + $repeatEnd = date('Y-m-d H:i:s', $i + $diff); + $this->add_event( + $start, + $repeatEnd, + $allDay, + $title, + $content, + $sentTo, + false, + $eventId + ); + } + break; + case 'weekly': + for ($i = $origStartDate + 604800; $i <= $end; $i += 604800) { + $start = date('Y-m-d H:i:s', $i); + $repeatEnd = date('Y-m-d H:i:s', $i + $diff); + $this->add_event( + $start, + $repeatEnd, + $allDay, + $title, + $content, + $sentTo, + false, + $eventId + ); + } + break; + case 'monthlyByDate': + $next_start = $this->addMonth($origStartDate); + while ($next_start <= $end) { + $start = date('Y-m-d H:i:s', $next_start); + $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff); + $this->add_event( + $start, + $repeatEnd, + $allDay, + $title, + $content, + $sentTo, + false, + $eventId + ); + $next_start = $this->addMonth($next_start); + } + break; + case 'monthlyByDay': + //not yet implemented + break; + case 'monthlyByDayR': + //not yet implemented + break; + case 'yearly': + $next_start = $this->addYear($origStartDate); + while ($next_start <= $end) { + $start = date('Y-m-d H:i:s', $next_start); + $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff); + $this->add_event( + $start, + $repeatEnd, + $allDay, + $title, + $content, + $sentTo, + false, + $eventId + ); + $next_start = $this->addYear($next_start); + } + break; + } + } - public function store_agenda_item_as_announcement($item_id, $sent_to = array()) + return true; + } + + /** + * @param int $item_id + * @param array $sentTo + * @return int + */ + public function store_agenda_item_as_announcement($item_id, $sentTo = array()) { $table_agenda = Database::get_course_table(TABLE_AGENDA); - $course_id = api_get_course_int_id(); + $course_id = api_get_course_int_id(); - //check params + // Check params if (empty($item_id) or $item_id != strval(intval($item_id))) { return -1; } - //get the agenda item + // 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); + $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)) { + // Sending announcement + if (!empty($sentTo)) { $id = AnnouncementManager::add_announcement( $row['title'], $row['content'], - $sent_to, + $sentTo, 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 + * @param int $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 $allDay is all day 'true' or 'false' + * @param string $title + * @param string $content + * @param array $usersToSend + * @param int $editRepeatType + * @param array $attachmentArray + * @param string $attachmentComment + * + * @return bool */ - public function edit_event($id, $start, $end, $all_day, $view, $title, $content) - { + public function edit_event( + $id, + $start, + $end, + $allDay, + $title, + $content, + $usersToSend = array(), + $attachmentArray = array(), + $attachmentComment = null + ) { $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(); + $end = api_get_utc_datetime($end); + $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0; switch ($this->type) { case 'personal': @@ -281,119 +502,362 @@ class Agenda 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)); + $attributes = array( + 'title' => $title, + 'text' => $content, + 'date' => $start, + 'enddate' => $end, + 'all_day' => $allDay + ); + 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)); + + if (empty($eventInfo)) { + return false; } - break; - case 'course': + + $groupId = api_get_group_id(); $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)); + + if (empty($course_id)) { + return false; } - 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) - { + if (api_is_allowed_to_edit(null, true)) { - 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); + $attributes = array( + 'title' => $title, + 'content' => $content, + 'start_date' => $start, + 'end_date' => $end, + 'all_day' => $allDay + ); - //Getting platform/admin events - $this->get_platform_events($start, $end); + Database::update( + $this->tbl_course_agenda, + $attributes, + array( + 'id = ? AND c_id = ? AND session_id = ? ' => array($id, $course_id, api_get_session_id()) + ) + ); - //Getting course events - $my_course_list = array(); + if (!empty($usersToSend)) { + $sendTo = $this->parseSendToArray($usersToSend); - 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); - } + $usersToDelete = array_diff($eventInfo['send_to']['users'], $sendTo['users']); + $usersToAdd = array_diff($sendTo['users'], $eventInfo['send_to']['users']); - 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); + $groupsToDelete = array_diff($eventInfo['send_to']['groups'], $sendTo['groups']); + $groupToAdd = array_diff($sendTo['groups'], $eventInfo['send_to']['groups']); + + if ($sendTo['everyone']) { + // Delete all: + if (!empty($eventInfo['send_to']['groups']) && + isset($eventInfo['send_to']['groups']) + ) { + foreach ($eventInfo['send_to']['groups'] as $group) { + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "delete", + api_get_user_id(), + $group, + 0, + $start, + $end, + $this->sessionId + ); + } } - } - } - } - 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) { + // storing the selected users + if (!empty($eventInfo['send_to']['users']) && + isset($eventInfo['send_to']['users']) + ) { + foreach ($eventInfo['send_to']['users'] as $userId) { + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "delete", + api_get_user_id(), + $groupId, + $userId, + $start, + $end, + $this->sessionId + ); + } + } + + // Add to everyone only. + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "visible", + api_get_user_id(), + $groupId, + '', + $start, + $end, + $this->sessionId + ); + } else { + // Groups + if (!empty($groupToAdd)) { + foreach ($groupToAdd as $group) { + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "visible", + api_get_user_id(), + $group, + 0, + $start, + $end, + $this->sessionId + ); + } + } + + if (!empty($groupsToDelete)) { + foreach ($groupsToDelete as $group) { + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "delete", + api_get_user_id(), + $group, + 0, + $start, + $end, + $this->sessionId + ); + } + } + + // Users. + if (!empty($usersToAdd)) { + foreach ($usersToAdd as $userId) { + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "visible", + api_get_user_id(), + $groupId, + $userId, + $start, + $end, + $this->sessionId + ); + } + } + + if (!empty($usersToDelete)) { + foreach ($usersToDelete as $userId) { + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + "delete", + api_get_user_id(), + $groupId, + $userId, + $start, + $end, + $this->sessionId + ); + } + } + } + } + + // Add announcement. + /*if (isset($addAsAnnouncement) && !empty($addAsAnnouncement)) { + $this->store_agenda_item_as_announcement($id); + }*/ + + // Add attachment. + if (isset($attachmentArray) && !empty($attachmentArray)) { + $this->updateAttachment( + $id, + $attachmentArray, + $attachmentComment, + $this->course + ); + } + } + break; + case 'admin': + case 'platform': + if (api_is_platform_admin()) { + $attributes = array( + 'title' => $title, + 'content' => $content, + 'start_date' => $start, + 'end_date' => $end, + 'all_day' => $allDay + ); + Database::update( + $this->tbl_global_agenda, + $attributes, + array('id = ?' => $id) + ); + } + break; + } + } + + /** + * @param int $id + * @param bool $deleteAllItemsFromSerie + */ + public function delete_event($id, $deleteAllItemsFromSerie = false) + { + 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)) { + // Delete + if ($deleteAllItemsFromSerie) { + $eventInfo = $this->get_event($id); + /* This is one of the children. + Getting siblings and delete 'Em all + the father! */ + if (isset($eventInfo['parent_event_id']) && !empty($eventInfo['parent_event_id'])) { + // Removing items. + $events = $this->getAllRepeatEvents($eventInfo['parent_event_id']); + if (!empty($events)) { + foreach ($events as $event) { + $this->delete_event($event['id']); + } + } + // Removing parent. + $this->delete_event($eventInfo['parent_event_id']); + } else { + // This is the father looking for the children. + $events = $this->getAllRepeatEvents($id); + if (!empty($events)) { + foreach ($events as $event) { + $this->delete_event($event['id']); + } + } + } + } + + + // Removing from events. + Database::delete( + $this->tbl_course_agenda, + array('id = ? AND c_id = ?' => array($id, $course_id)) + ); + + api_item_property_update( + $this->course, + TOOL_CALENDAR_EVENT, + $id, + 'delete', + api_get_user_id() + ); + + // Removing from series. + Database::delete( + $this->table_repeat, + array('cal_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 + * @param int $end + * @param int $course_id + * @param int $groupId + * @param int $user_id + * @param string $format + * @return array|string + */ + public function get_events($start, $end, $course_id = null, $groupId = null, $user_id = 0, $format = 'json') + { + switch ($this->type) { + case 'admin': + $this->get_platform_events($start, $end); + break; + case 'course': + $session_id = api_get_session_id(); + $courseInfo = api_get_course_info_by_id($course_id); + $this->get_course_events( + $start, + $end, + $courseInfo, + $groupId, + $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) { + $courseInfo = api_get_course_info($course_item['code']); + $this->get_course_events($start, $end, $courseInfo, 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 { @@ -403,10 +867,18 @@ class Agenda } break; } + if (!empty($this->events)) { - return json_encode($this->events); - } + switch ($format) { + case 'json': + return json_encode($this->events); + break; + case 'array': + return $this->events; + break; + } + } return ''; } @@ -426,31 +898,29 @@ class Agenda 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) + $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); + 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) + $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); + 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) + $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); + Database::query($sql); break; } } - return 1; - } /** - * @param int $id - * @param int $day_delta - * @param int $minute_delta + * @param $id + * @param $day_delta + * @param $minute_delta * @return int */ public function move_event($id, $day_delta, $minute_delta) @@ -461,31 +931,30 @@ class Agenda $event = $this->get_event($id); - $all_day = 0; + $allDay = 0; if ($day_delta == 0 && $minute_delta == 0) { - $all_day = 1; + $allDay = 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) + $sql = "UPDATE $this->tbl_personal_agenda SET all_day = $allDay, 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) + $sql = "UPDATE $this->tbl_course_agenda SET all_day = $allDay, 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) + $sql = "UPDATE $this->tbl_global_agenda SET all_day = $allDay, 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; } @@ -498,246 +967,313 @@ class Agenda public function get_event($id) { // make sure events of the personal agenda can only be seen by the user himself - $id = intval($id); + $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(); + $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 = Database::fetch_array($result, 'ASSOC'); $event['description'] = $event['text']; - $event['start_date'] = $event['date']; - $event['end_date'] = $event['enddate']; + $event['content'] = $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; + $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 = Database::fetch_array($result, 'ASSOC'); $event['description'] = $event['content']; + + // Getting send to array + $event['send_to'] = $this->getUsersAndGroupSubscribedToEvent( + $id, + $this->course['real_id'], + $this->sessionId + ); + + // Getting repeat info + $event['repeat_info'] = $this->getRepeatedInfoByEvent( + $id, + $this->course['real_id'] + ); + + if (!empty($event['parent_event_id'])) { + $event['parent_info'] = $this->get_event($event['parent_event_id']); + } + + $event['attachment'] = $this->getAttachment($id, $this->course); } } break; case 'admin': case 'platform': - $sql = " SELECT * FROM ".$this->tbl_global_agenda." WHERE id=".$id; + $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 = 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 + * @param int $start + * @param int $end + * @return array */ 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); + $start = api_get_utc_datetime(intval($start)); + $end = api_get_utc_datetime(intval($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"; + WHERE date >= '".$start."' AND (enddate <='".$end."' OR enddate IS NULL) AND user = $user_id"; - $result = Database::query($sql); + $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 = 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['editable'] = true; $event['sent_to'] = get_lang('Me'); - $event['type'] = 'personal'; + $event['type'] = 'personal'; if (!empty($row['date']) && $row['date'] != '0000-00-00 00:00:00') { $event['start'] = $this->format_event_date($row['date']); + $event['start_date_localtime'] = api_get_local_time($row['date']); } if (!empty($row['enddate']) && $row['enddate'] != '0000-00-00 00:00:00') { $event['end'] = $this->format_event_date($row['enddate']); + $event['end_date_localtime'] = api_get_local_time($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; + $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0; + + $event['parent_event_id'] = 0; + $event['has_children'] = 0; + + $my_events[] = $event; + $this->events[] = $event; } } - return $my_events; } + /** + * Get user/group list per event. + * + * @param int $eventId + * @param int $courseId + * @paraù int $sessionId + * + * @return array + */ + public function getUsersAndGroupSubscribedToEvent($eventId, $courseId, $sessionId) + { + $eventId = intval($eventId); + $courseId = intval($courseId); + $sessionId = intval($sessionId); + + $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA); + $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY); + + // Get sent_tos + $sql = "SELECT DISTINCT to_user_id, to_group_id + FROM $tbl_property ip + INNER JOIN $tlb_course_agenda agenda + ON (ip.ref = agenda.id AND ip.c_id = agenda.c_id) + WHERE + ip.tool = '".TOOL_CALENDAR_EVENT."' AND + ref = $eventId AND + ip.visibility = '1' AND + ip.c_id = $courseId AND + ip.id_session = $sessionId + "; + + $result = Database::query($sql); + $users = array(); + $groups = array(); + $everyone = false; + + while ($row = Database::fetch_array($result, 'ASSOC')) { + if (!empty($row['to_group_id'])) { + $groups[] = $row['to_group_id']; + } + if (!empty($row['to_user_id'])) { + $users[] = $row['to_user_id']; + } + + if (empty($groups) && empty($users)) { + if ($row['to_group_id'] == 0) { + $everyone = true; + } + } + } + + return array( + 'everyone' => $everyone, + 'users' => $users, + 'groups' => $groups + ); + } + /** * @param int $start * @param int $end - * @param array $course_info - * @param int $group_id + * @param array $courseInfo + * @param int $groupId * @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) + public function get_course_events($start, $end, $courseInfo, $groupId = 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']); + $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null; + $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null; + + if (empty($courseInfo)) { + return array(); + } + $course_id = $courseInfo['real_id']; + if (empty($course_id)) { + return array(); + } + $user_id = intval($user_id); + + $groupList = GroupManager::get_group_list(null, $courseInfo['code']); $group_name_list = array(); - if (!empty($group_list)) { - foreach ($group_list as $group) { + if (!empty($groupList)) { + foreach ($groupList 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(); + $user_id = api_get_user_id(); } else { - $group_memberships = array_keys($group_name_list); + $group_memberships = GroupManager::get_group_ids($course_id, $user_id); } $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA); - $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY); - + $tbl_property = Database::get_course_table(TABLE_ITEM_PROPERTY); - if (!empty($group_id)) { - $group_memberships = array($group_id); + if (!empty($groupId)) { + $group_memberships = array($groupId); } $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 - ).") ) "; + if (!empty($groupId)) { + $where_condition = "( 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 - ).") ) "; + if (!empty($user_id)) { + $where_condition = "( ip.to_user_id = $user_id 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 - ).") ) "; + $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"; - + $sql = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref, to_user_id + FROM $tlb_course_agenda agenda INNER JOIN $tbl_property ip + ON (agenda.id = ip.ref AND agenda.c_id = ip.c_id) + WHERE + ip.tool ='".TOOL_CALENDAR_EVENT."' AND + $where_condition AND + ip.visibility = '1' AND + agenda.c_id = $course_id AND + ip.c_id = $course_id + "; } else { + $visibilityCondition = "ip.visibility='1' AND"; if (api_is_allowed_to_edit()) { - $where_condition = ""; + if ($user_id == 0) { + $where_condition = ""; + } else { + $where_condition = "( ip.to_user_id=".$user_id. ") AND "; + } + $visibilityCondition = " (ip.visibility IN ('1', '0')) AND "; } 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 + FROM $tlb_course_agenda agenda INNER JOIN $tbl_property ip + ON (agenda.id = ip.ref AND agenda.c_id = ip.c_id) + WHERE + ip.tool='".TOOL_CALENDAR_EVENT."' AND + $where_condition + $visibilityCondition + agenda.c_id = $course_id AND + ip.c_id = $course_id AND + agenda.session_id = $session_id AND + ip.id_session = $session_id "; + } + $dateCondition = null; + if (!empty($start) && !empty($end)) { + $dateCondition .= "AND ( + (agenda.start_date >= '".$start."' OR agenda.start_date IS NULL) AND + (agenda.end_date <= '".$end."' OR agenda.end_date IS NULL) + )"; } + $sql .= $dateCondition; + $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; - } - }*/ - + $eventId = $row['ref']; + $items = $this->getUsersAndGroupSubscribedToEvent($eventId, $course_id, $this->sessionId); + $group_to_array = $items['groups']; + $user_to_array = $items['users']; $event = array(); - $event['id'] = 'course_'.$row['id']; - //To avoid doubles + // To avoid doubles if (in_array($row['id'], $events_added)) { continue; } $events_added[] = $row['id']; - - $attachment = get_attachment($row['id'], $course_id); - - $has_attachment = ''; + $attachment = $this->getAttachment($row['id'], $courseInfo); 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); + $has_attachment = Display::return_icon('attachment.gif', get_lang('Attachment')); + $user_filename = $attachment['filename']; + $url = api_get_path(WEB_CODE_PATH).'calendar/download.php?file='.$attachment['path'].'&course_id='.$course_id.'&'.api_get_cidreq(); + $event['attachment'] = $has_attachment.Display::url($user_filename, $url); } else { $event['attachment'] = ''; } - $event['title'] = $row['title']; + $event['title'] = $row['title']; $event['className'] = 'course'; - $event['allDay'] = 'false'; - + $event['allDay'] = 'false'; $event['course_id'] = $course_id; $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color; @@ -757,19 +1293,20 @@ class Agenda if (!empty($row['start_date']) && $row['start_date'] != '0000-00-00 00:00:00') { $event['start'] = $this->format_event_date($row['start_date']); + $event['start_date_localtime'] = api_get_local_time($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['end_date_localtime'] = api_get_local_time($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? + // Event Sent to a group? if (isset($row['to_group_id']) && !empty($row['to_group_id'])) { $sent_to = array(); if (!empty($group_to_array)) { @@ -777,10 +1314,10 @@ class Agenda $sent_to[] = $group_name_list[$group_item]; } } - $sent_to = implode('@@', $sent_to); - $sent_to = str_replace('@@', '
', $sent_to); + $sent_to = implode('@@', $sent_to); + $sent_to = str_replace('@@', '
', $sent_to); $event['sent_to'] = '
'.$sent_to.'
'; - $event['type'] = 'group'; + $event['type'] = 'group'; } //Event sent to a user? @@ -789,16 +1326,13 @@ class Agenda 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 - ); + // Add username as tooltip for $event['sent_to'] - ref #4226 + $username = api_htmlentities(sprintf(get_lang('LoginX'), $user_info['username']), ENT_QUOTES); $sent_to[] = "".$user_info['complete_name'].""; } } - $sent_to = implode('@@', $sent_to); - $sent_to = str_replace('@@', '
', $sent_to); + $sent_to = implode('@@', $sent_to); + $sent_to = str_replace('@@', '
', $sent_to); $event['sent_to'] = '
'.$sent_to.'
'; } @@ -808,45 +1342,47 @@ class Agenda } $event['description'] = $row['content']; - $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0; + $event['visibility'] = $row['visibility']; + $event['real_id'] = $row['id']; + $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0; + $event['parent_event_id'] = $row['parent_event_id']; + $event['has_children'] = $this->hasChildren($row['id'], $course_id) ? 1 : 0; $this->events[] = $event; } } - return $this->events; } /** - * @param int $start - * @param int $end + * @param int $start tms + * @param int $end tms * @return array */ public function get_platform_events($start, $end) { $start = intval($start); - $end = intval($end); + $end = intval($end); $start = api_get_utc_datetime($start); - $end = api_get_utc_datetime($end); + $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 "; + WHERE start_date >= '".$start."' AND end_date <= '".$end."' AND access_url_id = $access_url_id "; - $result = Database::query($sql); + $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 = 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['editable'] = false; $event['type'] = 'admin'; if (api_is_platform_admin() && $this->type == 'admin') { @@ -855,28 +1391,33 @@ class Agenda if (!empty($row['start_date']) && $row['start_date'] != '0000-00-00 00:00:00') { $event['start'] = $this->format_event_date($row['start_date']); + $event['start_date_localtime'] = api_get_local_time($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['end_date_localtime'] = api_get_local_time($row['end_date']); } $event['description'] = $row['content']; - $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0; + $event['allDay'] = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0; - $my_events[] = $event; + $event['parent_event_id'] = 0; + $event['has_children'] = 0; + + $my_events[] = $event; $this->events[] = $event; } } - return $my_events; } /** * Format needed for the Fullcalendar js lib - * @param string UTC time - * @return string + * + * @param string $utc_time + * @return bool|string */ - public function format_event_date($utc_time) + function format_event_date($utc_time) { return date('c', api_strtotime(api_get_local_time($utc_time))); } @@ -884,15 +1425,11 @@ class Agenda /** * this function shows the form with the user that were not selected * @author: Patrick Cool , Ghent University - * @return string html code + * @return string code */ - static function construct_not_selected_select_form( - $group_list = null, - $user_list = null, - $to_already_selected = array() - ) { - $html = ''; if ($to_already_selected == 'everyone') { $html .= ''; } else { @@ -922,372 +1459,558 @@ class Agenda 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 .= ''; + $html .= ''; } } if (is_array($group_list)) { $html .= ''; $html .= ""; } - return $html; } - static function construct_not_selected_select_form_validator( + /** + * @param FormValidator $form + * @param array $groupList + * @param array $userList + * @param array $sendTo array('users' => [1, 2], 'groups' => [3, 4]) + * @param array $attributes + * @param bool $addOnlyItemsInSendTo + */ + public function setSendToSelect( $form, - $group_list = null, - $user_list = null, - $to_already_selected = array() + $groupList = null, + $userList = null, + $sendTo = array(), + $attributes = array(), + $addOnlyItemsInSendTo = false ) { - $params = array( - 'id' => 'users_to_send_id', + 'id' => 'users_to_send_id', 'data-placeholder' => get_lang('Select'), - 'multiple' => 'multiple', - 'style' => 'width:250px', - 'class' => 'chzn-select' + 'multiple' => 'multiple', + 'style' => 'width:250px', + 'class' => 'chzn-select' ); + if (!empty($attributes)) { + $params = array_merge($params, $attributes); + if (empty($params['multiple'])) { + unset($params['multiple']); + } + } + + $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : array(); + $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : array(); + + /** @var HTML_QuickForm_select $select */ $select = $form->addElement('select', 'users_to_send', get_lang('To'), null, $params); - $select->addOption(get_lang('Everyone'), 'everyone'); + $selectedEveryoneOptions = array(); + if (isset($sendTo['everyone']) && $sendTo['everyone']) { + $selectedEveryoneOptions = array('selected'); + $sendToUsers = array(); + } + + $select->addOption(get_lang('Everyone'), 'everyone', $selectedEveryoneOptions); $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 = " – $count_users ".get_lang('Users'); - $options[] = array( - 'text' => $this_group['name'].$count_users, - 'value' => "GROUP:".$this_group['id'] - ); + if (is_array($groupList)) { + foreach ($groupList as $group) { + $count_users = isset($group['count_users']) ? $group['count_users'] : $group['userNb']; + $count_users = " – $count_users ".get_lang('Users'); + $option = array( + 'text' => $group['name'].$count_users, + 'value' => "GROUP:".$group['id'] + ); + $selected = in_array($group['id'], $sendToGroups) ? true : false; + if ($selected) { + $option['selected'] = 'selected'; + } + + if ($addOnlyItemsInSendTo) { + if ($selected) { + $options[] = $option; + } + } else { + $options[] = $option; } } $select->addOptGroup($options, get_lang('Groups')); } + // adding the individual users to the select form - if (is_array($group_list)) { + if (is_array($userList)) { $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