Files
MYSOPHAL/inc/planningexternalevent.class.php
2025-08-07 13:15:31 +01:00

518 lines
16 KiB
PHP

<?php
/**
* ---------------------------------------------------------------------
* GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2015-2020 Teclib' and contributors.
*
* http://glpi-project.org
*
* based on GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* GLPI is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}
use Glpi\CalDAV\Contracts\CalDAVCompatibleItemInterface;
use Glpi\CalDAV\Traits\VobjectConverterTrait;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VTodo;
class PlanningExternalEvent extends CommonDBTM implements CalDAVCompatibleItemInterface {
use Glpi\Features\PlanningEvent {
rawSearchOptions as protected trait_rawSearchOptions;
}
use VobjectConverterTrait;
public $dohistory = true;
static $rightname = 'externalevent';
const MANAGE_BG_EVENTS = 1024;
static function getTypeName($nb = 0) {
return _n('External event', 'External events', $nb);
}
function defineTabs($options = []) {
$ong = [];
$this->addDefaultFormTab($ong);
$this->addStandardTab('Document_Item', $ong, $options);
$this->addStandardTab('Log', $ong, $options);
return $ong;
}
static function canUpdate() {
// we permits globally to update this object,
// as users can update their onw items
return Session::haveRightsOr(self::$rightname, [
CREATE,
UPDATE,
self::MANAGE_BG_EVENTS
]);
}
function canUpdateItem() {
if (!$this->canUpdateBGEvents()) {
return false;
}
// the current user can update only this own events without UPDATE right
// but not bg one, see above
if ($this->fields['users_id'] != Session::getLoginUserID()
&& !Session::haveRight(self::$rightname, UPDATE)) {
return false;
}
return parent::canUpdateItem();
}
function canPurgeItem() {
if (!$this->canUpdateBGEvents()) {
return false;
}
// the current user can update only this own events without PURGE right
// but not bg one, see above
if ($this->fields['users_id'] != Session::getLoginUserID()
&& !Session::haveRight(self::$rightname, PURGE)) {
return false;
}
return parent::canPurgeItem();
}
/**
* do we have the right to manage background events
*
* @return bool
*/
function canUpdateBGEvents() {
if ($this->fields["background"]
&& !Session::haveRight(self::$rightname, self::MANAGE_BG_EVENTS)) {
return false;
}
return true;
}
function post_getFromDB() {
$this->fields['users_id_guests'] = importArrayFromDB($this->fields['users_id_guests']);
}
function showForm($ID, $options = []) {
global $CFG_GLPI;
$canedit = $this->can($ID, UPDATE);
$rand = mt_rand();
$rand_plan = mt_rand();
$rand_rrule = mt_rand();
$this->initForm($ID, $options);
$this->showFormHeader($options);
$is_ajax = isset($options['from_planning_edit_ajax']) && $options['from_planning_edit_ajax'];
$is_rrule = strlen($this->fields['rrule']) > 0;
// set event for another user
if (isset($options['res_itemtype'])
&& isset($options['res_items_id'])
&& strtolower($options['res_itemtype']) == "user") {
$this->fields['users_id'] = $options['res_items_id'];
}
if ($canedit) {
$tpl_class = 'PlanningExternalEventTemplate';
echo "<tr class='tab_bg_1' style='vertical-align: top'>";
echo "<td colspan='2'>".$tpl_class::getTypeName()."</td>";
echo "<td colspan='2'>";
$planning_id = $this->fields['planningexternaleventtemplates_id'];
parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $queries);
if(isset($queries['planningtitre']) && !empty($queries['planningtitre'])){
$planning_titre = $queries['planningtitre'];
switch ($planning_titre) {
case "Revue Annuelle Plan Directeur Approvisionnements":
$planning_id = 4;
break;
case "Revue Annuelle Plan Directeur Commercial":
$planning_id = 1;
break;
case "Revue Annuelle Plan Directeur Marketing":
$planning_id = 2;
break;
case "Revue Annuelle Plan Directeur Production":
$planning_id = 3;
break;
case "Revue Annuelle Plan Directeur Ressources Humaines":
$planning_id = 5;
break;
case "Revue Annuelle Plan Directeur Système Information":
$planning_id = 6;
break;
case "Revue Mensuelle Suivi Commercial":
$planning_id = 7;
break;
case "Revue Mensuelle Suivi Marketing":
$planning_id = 8;
break;
case "Revue Mensuelle Suivi Production":
$planning_id = 9;
break;
case "Revue Mensuelle Suivi Approvisionnement":
$planning_id = 10;
break;
case "Revue Mensuelle Suivi Ressources Humaines":
$planning_id = 11;
break;
case "Revue Mensuelle Suivi Système Information":
$planning_id = 12;
break;
}
}
$tpl_class::dropdown([
'value' => $planning_id,
'entity' => $this->getEntityID(),
'rand' => $rand,
'on_change' => "template_update$rand(this.value)"
]);
$ajax_url = $CFG_GLPI["root_doc"]."/ajax/planning.php";
$JS = <<<JAVASCRIPT
function template_update{$rand}(value) {
$.ajax({
url: '{$ajax_url}',
type: "POST",
data: {
action: 'get_externalevent_template',
planningexternaleventtemplates_id: value
}
}).done(function(data) {
// set common fields
if (data.name.length > 0) {
$("#textfield_name{$rand}").val(data.name);
}
$("#dropdown_state{$rand}").trigger("setValue", data.state);
if (data.planningeventcategories_id > 0) {
$("#dropdown_planningeventcategories_id{$rand}")
.trigger("setValue", data.planningeventcategories_id);
}
$("#dropdown_background{$rand}").trigger("setValue", data.background);
if (data.text.length > 0) {
if (contenttinymce = tinymce.get("text{$rand}")) {
contenttinymce.setContent(data.text);
$("#text{$rand}").val(data.text);
}
}
// set planification fields
if (data.duration > 0) {
$("#dropdown_plan__duration_{$rand_plan}").trigger("setValue", data.duration);
}
$("#dropdown__planningrecall_before_time_{$rand_plan}")
.trigger("setValue", data.before_time);
// set rrule fields
if (data.rrule != null
&& data.rrule.freq != null ) {
$("#dropdown_rrule_freq_{$rand_rrule}").trigger("setValue", data.rrule.freq);
$("#dropdown_rrule_interval_{$rand_rrule}").trigger("setValue", data.rrule.interval);
$("#showdate{$rand_rrule}").val(data.rrule.until);
$("#dropdown_rrule_byday_{$rand_rrule}").val(data.rrule.byday).trigger('change');
$("#dropdown_rrule_bymonth_{$rand_rrule}").val(data.rrule.bymonth).trigger('change');
}
});
}
JAVASCRIPT;
echo Html::scriptBlock($JS);
if($ID == ''){
echo"<script>
$( document ).ready(function() {
var id = '{$planning_id}';
if( id != '') template_update{$rand}({$planning_id});
});
</script>";
}
echo "</tr>";
}
echo "<tr class='tab_bg_2'><td colspan='2'>".__('Title')."</td>";
echo "<td colspan='2'>";
if (isset($options['start'])) {
echo Html::hidden('day', ['value' => $options['start']]);
}
if ($canedit) {
Html::autocompletionTextField($this, "name", [
'size' => '80',
'entity' => -1,
'user' => $this->fields["users_id"],
'rand' => $rand
]);
} else {
echo $this->fields['name'];
}
if (isset($options['from_planning_edit_ajax']) && $options['from_planning_edit_ajax']) {
echo Html::hidden('from_planning_edit_ajax');
}
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_2'><td colspan='2'>".User::getTypeName(1)."</td>";
echo "<td colspan='2'>";
User::dropdown([
'name' => 'users_id',
'right' => 'all',
'value' => $this->fields['users_id']
]);
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_2'><td colspan='2'>".__('Guests')."</td>";
echo "<td colspan='2'>";
User::dropdown([
'name' => 'users_id_guests[]',
'right' => 'all',
'values' => $this->fields['users_id_guests'],
'specific_tags' => [
'multiple' => true
],
]);
echo "<div style='font-style: italic'>".
__("Each guest will have a read-only copy of this event").
"</div>";
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_2'>";
echo "<td colspan='2'>".__('Status')."</td>";
echo "<td colspan='2'>";
if ($canedit) {
Planning::dropdownState("state", $this->fields["state"], true, [
'rand' => $rand,
]);
} else {
echo Planning::getState($this->fields["state"]);
}
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_2'>";
echo "<tr class='tab_bg_2'>";
echo "<td colspan='2'>".__('Category')."</td>";
echo "<td colspan='2'>";
if ($canedit) {
PlanningEventCategory::dropdown([
'value' => $this->fields['planningeventcategories_id'],
'rand' => $rand
]);
} else {
echo Dropdown::getDropdownName(
PlanningEventCategory::getTable(),
$this->fields['planningeventcategories_id']
);
}
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_2'>";
echo "<td colspan='2'>".__('Background event')."</td>";
echo "<td colspan='2'>";
if ($canedit) {
Dropdown::showYesNo('background', $this->fields['background'], -1, [
'rand' => $rand,
]);
} else {
echo Dropdown::getYesNo($this->fields['background']);
}
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_2'><td colspan='2'>"._n('Calendar', 'Calendars', 1)."</td>";
echo "<td>";
Planning::showAddEventClassicForm([
'items_id' => $this->fields['id'],
'itemtype' => $this->getType(),
'begin' => $this->fields['begin'],
'end' => $this->fields['end'],
'rand_user' => $this->fields['users_id'],
'rand' => $rand_plan,
]);
echo "</td></tr>";
echo "<tr class='tab_bg_2'><td colspan='2'>".__('Repeat')."</td>";
echo "<td>";
echo self::showRepetitionForm($this->fields['rrule'] ?? '', [
'rand' => $rand_rrule
]);
echo "</td></tr>";
echo "<tr class='tab_bg_2'><td>".__('Description')."</td>".
"<td colspan='3'>";
if ($canedit) {
Html::textarea([
'name' => 'text',
'value' => $this->fields["text"],
'enable_richtext' => true,
'enable_fileupload' => true,
'rand' => $rand,
'editor_id' => 'text'.$rand,
]);
} else {
echo "<div>";
echo Toolbox::unclean_html_cross_side_scripting_deep($this->fields["text"]);
echo "</div>";
}
echo "</td></tr>";
if ($is_ajax && $is_rrule) {
$options['candel'] = false;
$options['addbuttons'] = [
'purge' => "<i class='fas fa-trash-alt'></i>&nbsp;".__("Delete serie"),
'purge_instance' => "<i class='far fa-trash-alt'></i>&nbsp;".__("Delete instance"),
];
}
$this->showFormButtons($options);
return true;
}
function getRights($interface = 'central') {
$values = parent::getRights();
$values[self::MANAGE_BG_EVENTS] = __('manage background events');
return $values;
}
function cleanDBonPurge() {
$this->deleteChildrenAndRelationsFromDb(
[
VObject::class,
]
);
}
public static function getGroupItemsAsVCalendars($groups_id) {
return self::getItemsAsVCalendars([self::getTableField('groups_id') => $groups_id]);
}
public static function getUserItemsAsVCalendars($users_id) {
return self::getItemsAsVCalendars([
'OR' => [
self::getTableField('users_id') => $users_id,
self::getTableField('users_id_guests') => ['LIKE', '%"'.$users_id.'"%'],
]
]);
}
/**
* Returns items as VCalendar objects.
*
* @param array $criteria
*
* @return \Sabre\VObject\Component\VCalendar[]
*/
private static function getItemsAsVCalendars(array $criteria) {
global $DB;
$query = [
'FROM' => self::getTable(),
'WHERE' => $criteria,
];
$event_iterator = $DB->request($query);
$vcalendars = [];
foreach ($event_iterator as $event) {
$item = new self();
$item->getFromResultSet($event);
$vcalendar = $item->getAsVCalendar();
if (null !== $vcalendar) {
$vcalendars[] = $vcalendar;
}
}
return $vcalendars;
}
public function getAsVCalendar() {
if (!$this->canViewItem()) {
return null;
}
// Transform HTML text to plain text
$this->fields['text'] = Html::clean(
Toolbox::unclean_cross_side_scripting_deep(
$this->fields['text']
)
);
$is_task = in_array($this->fields['state'], [Planning::DONE, Planning::TODO]);
$is_planned = !empty($this->fields['begin']) && !empty($this->fields['end']);
$target_component = $this->getTargetCaldavComponent($is_planned, $is_task);
if (null === $target_component) {
return null;
}
$vcalendar = $this->getVCalendarForItem($this, $target_component);
return $vcalendar;
}
public function getInputFromVCalendar(VCalendar $vcalendar) {
$vcomp = $vcalendar->getBaseComponent();
$input = $this->getCommonInputFromVcomponent($vcomp, $this->isNewItem());
$input['text'] = $input['content'];
unset($input['content']);
if ($vcomp instanceof VTodo && !array_key_exists('state', $input)) {
// Force default state to TO DO or event will be considered as VEVENT
$input['state'] = \Planning::TODO;
}
return $input;
}
function rawSearchOptions() {
return $this->trait_rawSearchOptions();
}
}