1<?php 2 3/* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */ 4 5require_once("./Services/COPage/classes/class.ilPageContent.php"); 6 7/** 8* Class ilPCSection 9* 10* Section content object (see ILIAS DTD) 11* 12* @author Alex Killing <alex.killing@gmx.de> 13* @version $Id$ 14* 15* @ingroup ServicesCOPage 16*/ 17class ilPCSection extends ilPageContent 18{ 19 /** 20 * @var ilAccessHandler 21 */ 22 protected $access; 23 24 /** 25 * @var ilCtrl 26 */ 27 protected $ctrl; 28 29 /** 30 * @var ilLanguage 31 */ 32 protected $lng; 33 34 public $dom; 35 public $sec_node; 36 37 /** 38 * Init page content component. 39 */ 40 public function init() 41 { 42 global $DIC; 43 44 $this->access = $DIC->access(); 45 $this->ctrl = $DIC->ctrl(); 46 $this->lng = $DIC->language(); 47 $this->setType("sec"); 48 } 49 50 /** 51 * Set node 52 */ 53 public function setNode($a_node) 54 { 55 parent::setNode($a_node); // this is the PageContent node 56 $this->sec_node = $a_node->first_child(); // this is the Section node 57 } 58 59 /** 60 * Create section node in xml. 61 * 62 * @param object $a_pg_obj Page Object 63 * @param string $a_hier_id Hierarchical ID 64 */ 65 public function create(&$a_pg_obj, $a_hier_id, $a_pc_id = "") 66 { 67 $this->node = $this->createPageContentNode(); 68 $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id); 69 $this->sec_node = $this->dom->create_element("Section"); 70 $this->sec_node = $this->node->append_child($this->sec_node); 71 $this->sec_node->set_attribute("Characteristic", "Block"); 72 } 73 74 /** 75 * Set Characteristic of section 76 * 77 * @param string $a_char Characteristic 78 */ 79 public function setCharacteristic($a_char) 80 { 81 if (!empty($a_char)) { 82 $this->sec_node->set_attribute("Characteristic", $a_char); 83 } else { 84 if ($this->sec_node->has_attribute("Characteristic")) { 85 $this->sec_node->remove_attribute("Characteristic"); 86 } 87 } 88 } 89 90 /** 91 * Get characteristic of section. 92 * 93 * @return string characteristic 94 */ 95 public function getCharacteristic() 96 { 97 if (is_object($this->sec_node)) { 98 $char = $this->sec_node->get_attribute("Characteristic"); 99 if (substr($char, 0, 4) == "ilc_") { 100 $char = substr($char, 4); 101 } 102 return $char; 103 } 104 } 105 106 /** 107 * Get lang vars needed for editing 108 * @return array array of lang var keys 109 */ 110 public static function getLangVars() 111 { 112 return array("ed_insert_section"); 113 } 114 115 /** 116 * After page has been updated (or created) 117 * 118 * @param object $a_page page object 119 * @param DOMDocument $a_domdoc dom document 120 * @param string $a_xml xml 121 * @param bool $a_creation true on creation, otherwise false 122 */ 123 public static function afterPageUpdate($a_page, DOMDocument $a_domdoc, $a_xml, $a_creation) 124 { 125 include_once("./Services/COPage/classes/class.ilPCSection.php"); 126 self::saveTimings($a_page); 127 } 128 129 /** 130 * Modify page content after xsl 131 * 132 * @param string $a_output 133 * @return string 134 */ 135 public function modifyPageContentPostXsl($a_output, $a_mode) 136 { 137 $a_output = self::insertTimings($a_output); 138 $a_output = $this->handleAccess($a_output, $a_mode); 139 140 return $a_output; 141 } 142 143 /** 144 * Set activation from 145 * 146 * @param string $a_unix_ts unix ts activation from 147 */ 148 public function setActiveFrom($a_unix_ts) 149 { 150 if ($a_unix_ts > 0) { 151 $this->sec_node->set_attribute("ActiveFrom", $a_unix_ts); 152 } else { 153 if ($this->sec_node->has_attribute("ActiveFrom")) { 154 $this->sec_node->remove_attribute("ActiveFrom"); 155 } 156 } 157 } 158 159 /** 160 * Get activation from 161 * 162 * @return string unix ts activation from 163 */ 164 public function getActiveFrom() 165 { 166 if (is_object($this->sec_node)) { 167 return $this->sec_node->get_attribute("ActiveFrom"); 168 } 169 170 return ""; 171 } 172 173 /** 174 * Set activation to 175 * 176 * @param string $a_unix_ts unix ts activation to 177 */ 178 public function setActiveTo($a_unix_ts) 179 { 180 if ($a_unix_ts > 0) { 181 $this->sec_node->set_attribute("ActiveTo", $a_unix_ts); 182 } else { 183 if ($this->sec_node->has_attribute("ActiveTo")) { 184 $this->sec_node->remove_attribute("ActiveTo"); 185 } 186 } 187 } 188 189 /** 190 * Get activation to 191 * 192 * @return string unix ts activation to 193 */ 194 public function getActiveTo() 195 { 196 if (is_object($this->sec_node)) { 197 return $this->sec_node->get_attribute("ActiveTo"); 198 } 199 200 return ""; 201 } 202 203 /** 204 * Set attribute 205 * 206 * @param string $a_attr attribute 207 * @param string $a_val attribute value 208 */ 209 protected function setAttribute($a_attr, $a_val) 210 { 211 if (!empty($a_val)) { 212 $this->sec_node->set_attribute($a_attr, $a_val); 213 } else { 214 if ($this->sec_node->has_attribute($a_attr)) { 215 $this->sec_node->remove_attribute($a_attr); 216 } 217 } 218 } 219 220 /** 221 * Get attribute 222 * 223 * @param string $a_attr attribute 224 * @return string attribute value 225 */ 226 public function getAttribute($a_attr) 227 { 228 if (is_object($this->sec_node)) { 229 return $this->sec_node->get_attribute($a_attr); 230 } 231 return ""; 232 } 233 234 /** 235 * Set permission 236 * 237 * @param string $a_val "read"|"write"|"visible" 238 */ 239 public function setPermission($a_val) 240 { 241 $this->setAttribute("Permission", $a_val); 242 } 243 244 /** 245 * Get permission 246 * 247 * @return string 248 */ 249 public function getPermission() 250 { 251 return $this->getAttribute("Permission"); 252 } 253 254 255 /** 256 * Set permission ref id 257 * 258 * @param integer $a_ref_id ref id 259 */ 260 public function setPermissionRefId($a_ref_id) 261 { 262 $this->setAttribute("PermissionRefId", "il__ref_" . $a_ref_id); 263 } 264 265 /** 266 * Get permission ref id 267 * 268 * @return int ref id 269 */ 270 public function getPermissionRefId() 271 { 272 $id = explode("_", $this->getAttribute("PermissionRefId")); 273 if (in_array($id[1], array("", 0, IL_INST_ID))) { 274 return $id[3]; 275 } 276 return ""; 277 } 278 279 /** 280 * Set no link 281 */ 282 public function setNoLink() 283 { 284 ilDOMUtil::deleteAllChildsByName($this->sec_node, array("IntLink", "ExtLink")); 285 } 286 287 /** 288 * Set link of area to an external one 289 * @param string $a_href 290 */ 291 public function setExtLink($a_href) 292 { 293 $this->setNoLink(); 294 if (trim($a_href) != "") { 295 $attributes = array("Href" => trim($a_href)); 296 ilDOMUtil::setFirstOptionalElement( 297 $this->dom, 298 $this->sec_node, 299 "ExtLink", 300 array(""), 301 "", 302 $attributes 303 ); 304 } 305 } 306 307 /** 308 * Set link of area to an internal one 309 */ 310 public function setIntLink($a_type, $a_target, $a_target_frame) 311 { 312 $this->setNoLink(); 313 $attributes = array("Type" => $a_type, "Target" => $a_target, 314 "TargetFrame" => $a_target_frame); 315 ilDOMUtil::setFirstOptionalElement( 316 $this->dom, 317 $this->sec_node, 318 "IntLink", 319 array(""), 320 "", 321 $attributes 322 ); 323 } 324 325 /** 326 * Get link 327 * 328 * @param 329 * @return 330 */ 331 public function getLink() 332 { 333 $childs = $this->sec_node->child_nodes(); 334 foreach ($childs as $child) { 335 if ($child->node_name() == "ExtLink") { 336 return array("LinkType" => "ExtLink", 337 "Href" => $child->get_attribute("Href")); 338 } 339 if ($child->node_name() == "IntLink") { 340 return array("LinkType" => "IntLink", 341 "Target" => $child->get_attribute("Target"), 342 "Type" => $child->get_attribute("Type"), 343 "TargetFrame" => $child->get_attribute("TargetFrame")); 344 } 345 } 346 return array("LinkType" => "NoLink"); 347 } 348 349 350 /** 351 * @param $a_html 352 * @param $a_mode 353 * @return mixed|string 354 */ 355 public function handleAccess($a_html, $a_mode) 356 { 357 $ilAccess = $this->access; 358 359 while (($start = strpos($a_html, "{{{{{Section;Access;")) > 0) { 360 $end = strpos($a_html, "}}}}}", $start); 361 $access_attr = explode(";", substr($a_html, $start, $end - $start)); 362 $id = explode("_", $access_attr[3]); 363 $section_nr = $access_attr[6]; 364 $access = true; 365 366 if (in_array($id[1], array("", 0, IL_INST_ID)) && $id[3] > 0) { 367 $access = $ilAccess->checkAccess($access_attr[5], "", $id[3]); 368 } 369 $end_limiter = "{{{{{Section;AccessEnd;".$section_nr."}}}}}"; 370 if ($access) { 371 $a_html = substr($a_html, 0, $start) . substr($a_html, $end + 5); 372 $a_html = str_replace($end_limiter, "", $a_html); 373 } else { 374 $end = strpos($a_html, $end_limiter, $start); 375 $a_html = substr($a_html, 0, $start) . substr($a_html, $end + strlen($end_limiter)); 376 } 377 } 378 379 $a_html = str_replace("{{{{{Section;Access}}}}}", "", $a_html); 380 381 return $a_html; 382 } 383 384 /** 385 * Save timings 386 * 387 * @param ilPageObject $a_page page object 388 */ 389 public static function saveTimings($a_page) 390 { 391 global $DIC; 392 393 $ilDB = $DIC->database(); 394 395 $ilDB->manipulate( 396 "DELETE FROM copg_section_timings WHERE " . 397 " page_id = " . $ilDB->quote($a_page->getId(), "integer") . 398 " AND parent_type = " . $ilDB->quote($a_page->getParentType(), "text") 399 ); 400 401 $xml = $a_page->getXMLFromDom(); 402 403 $doc = domxml_open_mem($xml); 404 405 // media aliases 406 $xpc = xpath_new_context($doc); 407 $path = "//Section"; 408 $res = xpath_eval($xpc, $path); 409 for ($i = 0; $i < count($res->nodeset); $i++) { 410 $from = $res->nodeset[$i]->get_attribute("ActiveFrom"); 411 if ($from != "") { 412 $ilDB->replace( 413 "copg_section_timings", 414 array( 415 "page_id" => array("integer", $a_page->getId()), 416 "parent_type" => array("text", $a_page->getParentType()), 417 "unix_ts" => array("integer", $from) 418 ), 419 array() 420 ); 421 } 422 $to = $res->nodeset[$i]->get_attribute("ActiveTo"); 423 if ($to != "") { 424 $ilDB->replace( 425 "copg_section_timings", 426 array( 427 "page_id" => array("integer", $a_page->getId()), 428 "parent_type" => array("text", $a_page->getParentType()), 429 "unix_ts" => array("integer", $to) 430 ), 431 array() 432 ); 433 } 434 } 435 } 436 437 /** 438 * Get page cache update trigger string 439 * 440 * @param ilPageObject $a_page 441 * @return string trigger string 442 */ 443 public static function getCacheTriggerString($a_page) 444 { 445 global $DIC; 446 447 $ilDB = $DIC->database(); 448 449 $set = $ilDB->query( 450 "SELECT * FROM copg_section_timings " . 451 " WHERE page_id = " . $ilDB->quote($a_page->getId(), "integer") . 452 " AND parent_type = " . $ilDB->quote($a_page->getParentType(), "text") 453 ); 454 $str = "1"; // changed to 1 to force cache miss for #24277 455 $current_ts = new ilDateTime(time(), IL_CAL_UNIX); 456 $current_ts = $current_ts->get(IL_CAL_UNIX); 457 while ($rec = $ilDB->fetchAssoc($set)) { 458 $unix_ts = $rec["unix_ts"]; 459 if ($unix_ts < $current_ts) { 460 $unix_ts .= "a"; 461 } 462 $str .= "-" . $unix_ts; 463 } 464 465 return $str; 466 } 467 468 /** 469 * Insert timings (in edit mode) 470 * 471 * @param string $a_html html 472 * @return string htmls 473 */ 474 public function insertTimings($a_html) 475 { 476 $ilCtrl = $this->ctrl; 477 $lng = $this->lng; 478 479 $c_pos = 0; 480 $start = strpos($a_html, "{{{{{Section;ActiveFrom"); 481 if (is_int($start)) { 482 $end = strpos($a_html, "}}}}}", $start); 483 } 484 $i = 1; 485 while ($end > 0) { 486 $param = substr($a_html, $start + 13, $end - $start - 13); 487 $param = explode(";", $param); 488 $from = $param[1]; 489 $to = $param[3]; 490 $html = ""; 491 if ($from != "") { 492 ilDatePresentation::setUseRelativeDates(false); 493 $from = new ilDateTime($from, IL_CAL_UNIX); 494 $html .= $lng->txt("cont_active_from") . ": " . ilDatePresentation::formatDate($from); 495 } 496 if ($to != "") { 497 $to = new ilDateTime($to, IL_CAL_UNIX); 498 $html .= " " . $lng->txt("cont_active_to") . ": " . ilDatePresentation::formatDate($to); 499 } 500 501 $h2 = substr($a_html, 0, $start) . 502 $html . 503 substr($a_html, $end + 5); 504 $a_html = $h2; 505 $i++; 506 507 $start = strpos($a_html, "{{{{{Section;ActiveFrom;", $start + 5); 508 $end = 0; 509 if (is_int($start)) { 510 $end = strpos($a_html, "}}}}}", $start); 511 } 512 } 513 return $a_html; 514 } 515} 516