1<?php 2 3################################################################# 4# Copyright notice 5# 6# (c) 2013 Jérôme Schneider <mail@jeromeschneider.fr> 7# All rights reserved 8# 9# http://sabre.io/baikal 10# 11# This script is part of the Baïkal Server project. The Baïkal 12# Server project is free software; you can redistribute it 13# and/or modify it under the terms of the GNU General Public 14# License as published by the Free Software Foundation; either 15# version 2 of the License, or (at your option) any later version. 16# 17# The GNU General Public License can be found at 18# http://www.gnu.org/copyleft/gpl.html. 19# 20# This script is distributed in the hope that it will be useful, 21# but WITHOUT ANY WARRANTY; without even the implied warranty of 22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23# GNU General Public License for more details. 24# 25# This copyright notice MUST APPEAR in all copies of the script! 26################################################################# 27 28namespace Baikal\Model; 29 30use Symfony\Component\Yaml\Yaml; 31 32class Calendar extends \Flake\Core\Model\Db { 33 const DATATABLE = "calendarinstances"; 34 const PRIMARYKEY = "id"; 35 const LABELFIELD = "displayname"; 36 37 protected $aData = [ 38 "principaluri" => "", 39 "displayname" => "", 40 "uri" => "", 41 "description" => "", 42 "calendarorder" => 0, 43 "calendarcolor" => "", 44 "timezone" => null, 45 "calendarid" => 0 46 ]; 47 protected $oCalendar; # Baikal\Model\Calendar\Calendar 48 49 function __construct($sPrimary = false) { 50 parent::__construct($sPrimary); 51 try { 52 $config = Yaml::parseFile(PROJECT_PATH_CONFIG . "baikal.yaml"); 53 $this->set("timezone", $config['system']["timezone"]); 54 } catch (\Exception $e) { 55 error_log('Error reading baikal.yaml file : ' . $e->getMessage()); 56 } 57 } 58 59 protected function initFloating() { 60 parent::initFloating(); 61 $this->oCalendar = new Calendar\Calendar(); 62 } 63 64 protected function initByPrimary($sPrimary) { 65 parent::initByPrimary($sPrimary); 66 $this->oCalendar = new Calendar\Calendar($this->get("calendarid")); 67 } 68 69 function persist() { 70 $this->oCalendar->persist(); 71 $this->aData["calendarid"] = $this->oCalendar->get("id"); 72 parent::persist(); 73 } 74 75 static function icon() { 76 return "icon-calendar"; 77 } 78 79 static function mediumicon() { 80 return "glyph-calendar"; 81 } 82 83 static function bigicon() { 84 return "glyph2x-calendar"; 85 } 86 87 function getEventsBaseRequester() { 88 $oBaseRequester = \Baikal\Model\Calendar\Event::getBaseRequester(); 89 $oBaseRequester->addClauseEquals( 90 "calendarid", 91 $this->get("calendarid") 92 ); 93 94 return $oBaseRequester; 95 } 96 97 function get($sPropName) { 98 if ($sPropName === "components") { 99 return $this->oCalendar->get($sPropName); 100 } 101 102 if ($sPropName === "todos") { 103 # TRUE if components contains VTODO, FALSE otherwise 104 if (($sComponents = $this->get("components")) !== "") { 105 $aComponents = explode(",", $sComponents); 106 } else { 107 $aComponents = []; 108 } 109 110 return in_array("VTODO", $aComponents); 111 } 112 113 if ($sPropName === "notes") { 114 # TRUE if components contains VJOURNAL, FALSE otherwise 115 if (($sComponents = $this->get("components")) !== "") { 116 $aComponents = explode(",", $sComponents); 117 } else { 118 $aComponents = []; 119 } 120 121 return in_array("VJOURNAL", $aComponents); 122 } 123 124 return parent::get($sPropName); 125 } 126 127 function set($sPropName, $sValue) { 128 if ($sPropName === "components") { 129 return $this->oCalendar->set($sPropName, $sValue); 130 } 131 132 if ($sPropName === "todos") { 133 if (($sComponents = $this->get("components")) !== "") { 134 $aComponents = explode(",", $sComponents); 135 } else { 136 $aComponents = []; 137 } 138 139 if ($sValue === true) { 140 if (!in_array("VTODO", $aComponents)) { 141 $aComponents[] = "VTODO"; 142 } 143 } else { 144 if (in_array("VTODO", $aComponents)) { 145 unset($aComponents[array_search("VTODO", $aComponents)]); 146 } 147 } 148 149 return $this->set("components", implode(",", $aComponents)); 150 } 151 152 if ($sPropName === "notes") { 153 if (($sComponents = $this->get("components")) !== "") { 154 $aComponents = explode(",", $sComponents); 155 } else { 156 $aComponents = []; 157 } 158 159 if ($sValue === true) { 160 if (!in_array("VJOURNAL", $aComponents)) { 161 $aComponents[] = "VJOURNAL"; 162 } 163 } else { 164 if (in_array("VJOURNAL", $aComponents)) { 165 unset($aComponents[array_search("VJOURNAL", $aComponents)]); 166 } 167 } 168 169 return $this->set("components", implode(",", $aComponents)); 170 } 171 172 return parent::set($sPropName, $sValue); 173 } 174 175 function formMorphologyForThisModelInstance() { 176 $oMorpho = new \Formal\Form\Morphology(); 177 178 $oMorpho->add(new \Formal\Element\Text([ 179 "prop" => "uri", 180 "label" => "Calendar token ID", 181 "validation" => "required,tokenid", 182 "popover" => [ 183 "title" => "Calendar token ID", 184 "content" => "The unique identifier for this calendar.", 185 ] 186 ])); 187 188 $oMorpho->add(new \Formal\Element\Text([ 189 "prop" => "displayname", 190 "label" => "Display name", 191 "validation" => "required", 192 "popover" => [ 193 "title" => "Display name", 194 "content" => "This is the name that will be displayed in your CalDAV client.", 195 ] 196 ])); 197 198 $oMorpho->add(new \Formal\Element\Text([ 199 "prop" => "calendarcolor", 200 "label" => "Calendar color", 201 "validation" => "color", 202 "popover" => [ 203 "title" => "Calendar color", 204 "content" => "This is the color that will be displayed in your CalDAV client.<br/>" . 205 "Must be supplied in format '#RRGGBBAA' (alpha channel optional) with hexadecimal values.<br/>" . 206 "This value is optional.", 207 ] 208 ])); 209 210 $oMorpho->add(new \Formal\Element\Text([ 211 "prop" => "description", 212 "label" => "Description" 213 ])); 214 215 $oMorpho->add(new \Formal\Element\Checkbox([ 216 "prop" => "todos", 217 "label" => "Todos", 218 "help" => "If checked, todos will be enabled on this calendar.", 219 ])); 220 221 $oMorpho->add(new \Formal\Element\Checkbox([ 222 "prop" => "notes", 223 "label" => "Notes", 224 "help" => "If checked, notes will be enabled on this calendar.", 225 ])); 226 227 if ($this->floating()) { 228 $oMorpho->element("uri")->setOption( 229 "help", 230 "Allowed characters are digits, lowercase letters and the dash symbol '-'." 231 ); 232 } else { 233 $oMorpho->element("uri")->setOption("readonly", true); 234 } 235 236 return $oMorpho; 237 } 238 239 function isDefault() { 240 return $this->get("uri") === "default"; 241 } 242 243 function hasInstances() { 244 $rSql = $GLOBALS["DB"]->exec_SELECTquery( 245 "count(*)", 246 "calendarinstances", 247 "calendarid" . "='" . $this->aData["calendarid"] . "'" 248 ); 249 250 if (($aRs = $rSql->fetch()) === false) { 251 return false; 252 } else { 253 reset($aRs); 254 255 return $aRs["count(*)"] > 1; 256 } 257 } 258 259 function destroy() { 260 $hasInstances = $this->hasInstances(); 261 if (!$hasInstances) { 262 $oEvents = $this->getEventsBaseRequester()->execute(); 263 foreach ($oEvents as $event) { 264 $event->destroy(); 265 } 266 } 267 268 parent::destroy(); 269 if (!$hasInstances) { 270 $this->oCalendar->destroy(); 271 } 272 } 273} 274