Moodle release 3.3rc1
[moodle.git] / backup / util / structure / base_optigroup.class.php
blobe3f0dfd181522939adae23529453b0d84e82d913
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * @package moodlecore
20 * @subpackage backup-structure
21 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * TODO: Finish phpdocs
27 /**
28 * Abstract class representing one optigroup for conditional branching
30 abstract class base_optigroup extends base_nested_element {
32 /** @var boolean flag indicating if multiple branches can be processed (true) or no (false) */
33 private $multiple;
35 /**
36 * Constructor - instantiates one base_optigroup, specifying its basic info
38 * @param string $name name of the element
39 * @param array $elements base_optigroup_elements of this group
40 * @param bool $multiple to decide if the group allows multiple branches processing or no
42 public function __construct($name, $elements = null, $multiple = false) {
43 parent::__construct($name);
44 $this->multiple = $multiple;
45 if (!empty($elements)) {
46 $this->add_children($elements);
50 // Public API starts here
52 /**
53 * Return the level of this element, that will be, the level of the parent (doesn't consume level)
54 * (note this os only a "cosmetic" effect (to_string) as fact as the real responsible for this
55 * is the corresponding structure_processor for the final output.
57 public function get_level() {
58 return $this->get_parent() == null ? 1 : $this->get_parent()->get_level();
61 public function to_string($showvalue = false) {
62 $indent = str_repeat(' ', $this->get_level()); // Indent output based in level (4cc)
63 $output = $indent . '!' . $this->get_name() . ' (level: ' . $this->get_level() . ')';
64 $children = $this->get_children();
65 if (!empty($children)) {
66 foreach ($this->get_children() as $child) {
67 $output .= PHP_EOL . $child->to_string($showvalue);
70 return $output;
73 // Forbidden API starts here
75 /**
76 * Adding attributes is forbidden
78 public function add_attributes($attributes) {
79 throw new base_element_struct_exception('optigroup_not_attributes');
82 /**
83 * Instantiating attributes is forbidden
85 protected function get_new_attribute($name) {
86 throw new base_element_struct_exception('optigroup_not_attributes');
89 /**
90 * Adding final elements is forbidden
92 public function add_final_elements($attributes) {
93 throw new base_element_struct_exception('optigroup_not_final_elements');
96 /**
97 * Instantiating final elements is forbidden
99 protected function get_new_final_element($name) {
100 throw new base_element_struct_exception('optigroup_not_final_elements');
103 // Protected API starts here
105 protected function add_children($elements) {
106 if ($elements instanceof base_nested_element) { // Accept 1 element, object
107 $elements = array($elements);
109 if (is_array($elements)) {
110 foreach ($elements as $element) {
111 $this->add_child($element);
113 } else {
114 throw new base_optigroup_exception('optigroup_elements_incorrect');
119 * Set the parent of the optigroup and, at the same time, process all the
120 * condition params in all the childs
122 protected function set_parent($element) {
123 parent::set_parent($element);
124 // Force condition param calculation in all children
125 foreach ($this->get_children() as $child) {
126 $child->set_condition($child->get_condition_param(), $child->get_condition_value());
131 * Recalculate all the used elements in the optigroup, observing
132 * restrictions and passing the new used to outer level
134 protected function add_used($element) {
135 $newused = array();
136 // Iterate over all the element useds, filling $newused and
137 // observing the multiple setting
138 foreach ($element->get_used() as $used) {
139 if (!in_array($used, $this->get_used())) { // it's a new one, add to $newused array
140 $newused[] = $used;
141 $this->set_used(array_merge($this->get_used(), array($used))); // add to the optigroup used array
142 } else { // it's an existing one, exception on multiple optigroups
143 if ($this->multiple) {
144 throw new base_optigroup_exception('multiple_optigroup_duplicate_element', $used);
148 // Finally, inform about newused to the next grand(parent/optigroupelement)
149 if ($newused && $this->get_parent()) {
150 $element->set_used($newused); // Only about the newused
151 $grandparent = $this->get_grandoptigroupelement_or_grandparent();
152 $grandparent->check_and_set_used($element);
156 protected function is_multiple() {
157 return $this->multiple;
162 * base_optigroup_exception to control all the errors while building the optigroups
164 * This exception will be thrown each time the base_optigroup class detects some
165 * inconsistency related with the building of the group
167 class base_optigroup_exception extends base_atom_exception {
170 * Constructor - instantiates one base_optigroup_exception
172 * @param string $errorcode key for the corresponding error string
173 * @param object $a extra words and phrases that might be required in the error string
174 * @param string $debuginfo optional debugging information
176 public function __construct($errorcode, $a = null, $debuginfo = null) {
177 parent::__construct($errorcode, $a, $debuginfo);