FusionDirectory
class_template.inc
Go to the documentation of this file.
1 <?php
2 /*
3  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
4  Copyright (C) 2014-2020 FusionDirectory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20 
28 {
29  protected $type;
30  protected $dn;
31  protected $needed;
32  protected $attrs;
33  protected $tabObject;
34  protected $attributes;
35 
36  protected $applied = FALSE;
37 
38  static protected $uiSpecialAttributes = ['dn','cn','uid','sn','givenName'];
39 
40  static function plInfo ()
41  {
42  return [
43  'plShortName' => _('Template'),
44  'plDescription' => _('Object template, used to create several objects with similar values'),
45  /* Categories for templates are computed in config class */
46  'plCategory' => [],
47 
48  'plProvidedAcls' => [
49  'template_cn' => _('Template name')
50  ]
51  ];
52  }
53 
54  static function getTemplatedTypes ()
55  {
56  $result = [];
57  $types = objects::types();
58  foreach ($types as $type) {
59  if (in_array($type, departmentManagement::getDepartmentTypes())) {
60  continue;
61  }
62  $infos = objects::infos($type);
63  if ($infos['templateActive']) {
64  $result[$type] = $infos['name'];
65  }
66  }
67  asort($result);
68  return $result;
69  }
70 
71  function __construct ($type, $dn)
72  {
73  $this->type = $type;
74  $this->dn = $dn;
75  list($this->attrs, $depends) = templateHandling::fetch($this->dn);
76  $this->needed = templateHandling::neededAttrs($this->attrs, $depends);
77  $this->needed[] = 'base';
78  $this->tabObject = objects::create($this->type);
79  /* Used to know which tab is activated */
80  $tempTabObject = objects::open($this->dn, $this->type);
81  $tempTabObject->setActiveTabs($this->tabObject);
82  $this->attributes = [];
83  foreach ($this->tabObject->by_object as $class => $tab) {
84  if ($tab->isActive()) {
85  $this->attributes[$class] = [];
86  $attrs = array_unique(array_merge($tab->getRequiredAttributes(), $this->needed));
87  foreach (array_keys($tab->attributesAccess) as $attr) {
88  if (!$tab->showInTemplate($attr, $this->attrs)) {
89  continue;
90  }
91  if (in_array($attr, $attrs)) {
92  $this->attributes[$class][] = $attr;
93  }
94  }
95  if (empty($this->attributes[$class])) {
96  /* Do not show empty sections */
97  unset($this->attributes[$class]);
98  }
99  }
100  }
101  }
102 
104  function reset ()
105  {
106  list($this->attrs, $depends) = templateHandling::fetch($this->dn);
107  // This is needed because it removes %askme% values from attrs
108  $this->needed = templateHandling::neededAttrs($this->attrs, $depends);
109  $this->needed[] = 'base';
110  $this->tabObject = objects::create($this->type);
111  /* Used to know which tab is activated */
112  $tempTabObject = objects::open($this->dn, $this->type);
113  $tempTabObject->setActiveTabs($this->tabObject);
114  $this->applied = FALSE;
115  }
116 
117  function getDn ()
118  {
119  return $this->dn;
120  }
121 
122  function getBase ()
123  {
124  if (is_object($this->tabObject)) {
125  return $this->tabObject->getBaseObject()->base;
126  } else {
127  $infos = objects::infos($this->type);
128  return dn2base($this->dn, 'ou=templates,'.$infos['ou']);
129  }
130  }
131 
132  function getNeeded (): array
133  {
134  return $this->attributes;
135  }
136 
137  function alterAttributes ($mandatories, $readonly, $hidden)
138  {
139  foreach ($mandatories as $class => $attrs) {
140  foreach ($attrs as $attr) {
141  if (!in_array($attr, $this->attributes[$class])) {
142  $this->attributes[$class][] = $attr;
143  }
144  $this->tabObject->by_object[$class]->attributesAccess[$attr]->setRequired(TRUE);
145  }
146  }
147  foreach ($readonly as $class => $attrs) {
148  foreach ($attrs as $attr) {
149  if (!in_array($attr, $this->attributes[$class])) {
150  $this->attributes[$class][] = $attr;
151  }
152  $this->tabObject->by_object[$class]->attributesAccess[$attr]->setDisabled(TRUE);
153  }
154  }
155  foreach ($hidden as $class => $attrs) {
156  foreach ($attrs as $attr) {
157  if (!in_array($attr, $this->attributes[$class])) {
158  $this->attributes[$class][] = $attr;
159  }
160  $this->tabObject->by_object[$class]->attributesAccess[$attr]->setDisabled(TRUE);
161  $this->tabObject->by_object[$class]->attributesAccess[$attr]->setVisible(FALSE);
162  }
163  }
164  }
165 
166  function getAttribute ($tab, $attr)
167  {
168  return $this->tabObject->by_object[$tab]->attributesAccess[$attr];
169  }
170 
171  function getAttributeTab ($attr)
172  {
173  foreach ($this->tabObject->by_object as $tab => $tabObject) {
174  if (isset($tabObject->attributesAccess[$attr])) {
175  return $tab;
176  }
177  }
178  }
179 
182  function serialize ()
183  {
184  $ret = [];
185  foreach ($this->tabObject->by_object as $class => $plugin) {
186  if (!isset($this->attributes[$class])) {
187  continue;
188  }
189  $ret[$class] = ['name' => $this->tabObject->by_name[$class], 'attrs' => []];
190  foreach ($this->attributes[$class] as $attr) {
191  $plugin->attributesAccess[$attr]->serializeAttribute($ret[$class]['attrs'], FALSE);
192  }
193  $ret[$class]['attrs_order'] = array_keys($ret[$class]['attrs']);
194  }
195 
196  return $ret;
197  }
198 
201  function deserialize ($values)
202  {
203  foreach ($values as $class => $class_values) {
204  $result = $this->tabObject->by_object[$class]->deserializeValues($class_values);
205  if ($result !== TRUE) {
206  return $result;
207  }
208  }
209  return TRUE;
210  }
211 
216  function getValues ()
217  {
218  $ret = [];
219  foreach ($this->tabObject->by_object as $class => $plugin) {
220  $ret[$class] = [];
221  foreach ($plugin->attributesAccess as $name => $attr) {
222  $ret[$class][$name] = $attr->getValue();
223  }
224  }
225 
226  return $ret;
227  }
228 
231  function setValues ($values, $ldapFormat = FALSE)
232  {
233  foreach ($values as $class => $class_values) {
234  foreach ($class_values as $name => $value) {
235  if ($ldapFormat) {
236  $value = $this->tabObject->by_object[$class]->attributesAccess[$name]->inputValue($value);
237  }
238  $this->tabObject->by_object[$class]->attributesAccess[$name]->setValue($value);
239  }
240  }
241  }
242 
243  public function readPost ()
244  {
245  foreach ($this->tabObject->by_object as $plugin) {
246  $plugin->readPost();
247  }
248  }
249 
250  public function update (): bool
251  {
252  foreach ($this->tabObject->by_object as $plugin) {
253  $plugin->update();
254  }
255  return TRUE;
256  }
257 
258  public function dialogOpened ()
259  {
260  return $this->tabObject->dialogOpened();
261  }
262 
263  public function render (): string
264  {
265  $smarty = get_smarty();
266  $sections = [];
267  $posted = [];
268  $smarty->assign('baseACL', 'rw');
269  foreach ($this->tabObject->by_object as $class => &$plugin) {
270  if (!isset($this->attributes[$class])) {
271  continue;
272  }
273  if ($plugin->is_modal_dialog()) {
274  $this->tabObject->current = $class;
275  return $plugin->render();
276  }
277  $attributesRendered = [];
278  foreach ($this->attributes[$class] as $attr) {
279  if ($plugin->attributesAccess[$attr]->getAclInfo() !== FALSE) {
280  // We assign ACLs so that attributes can use them in their template code
281  $smarty->assign($plugin->attributesAccess[$attr]->getAcl().'ACL', $plugin->aclGetPermissions($plugin->attributesAccess[$attr]->getAcl()));
282  }
283  $readable = $plugin->attrIsReadable($attr);
284  $writable = $plugin->attrIsWriteable($attr);
285  $plugin->attributesAccess[$attr]->renderAttribute($attributesRendered, FALSE, $readable, $writable);
286  }
287 
288  $smarty->assign('section', $this->tabObject->by_name[$class]);
289  $smarty->assign('sectionId', $class);
290  $smarty->assign('sectionClasses', ' fullwidth');
291  $smarty->assign('attributes', $attributesRendered);
292 
293  $posted[] = $class.'_posted';
294  $sections[] = $smarty->fetch(get_template_path('simpleplugin_section.tpl'));
295  }
296  unset($plugin);
297 
298  $smarty->assign('sections', $sections);
299  $smarty->assign('hiddenPostedInput', $posted);
300  $smarty->assign('focusedField', '');
301 
302  return $smarty->fetch(get_template_path('simpleplugin.tpl'));
303  }
304 
305  /* Apply template and current values to an object and returns it for saving or edition
306  * Cannot be called twice! If you need to, call reset between calls */
307  function apply ($targetdn = NULL)
308  {
309  if ($this->applied) {
310  trigger_error('Templates can’t be applied twice without calling reset before');
311  return;
312  }
313 
314  if ($targetdn !== NULL) {
315  $this->tabObject = objects::open($targetdn, $this->type);
316  unset($this->attrs['objectClass']['count']);
317  foreach ($this->tabObject->by_object as $class => $plugin) {
318  if ($plugin->isActive()) {
319  $this->attrs['objectClass'] = $plugin->mergeObjectClasses($this->attrs['objectClass']);
320  }
321  }
322  }
323 
324  foreach ($this->tabObject->by_object as $class => &$plugin) {
325  if (!isset($this->attributes[$class])) {
326  continue;
327  }
328  foreach ($this->attributes[$class] as $attr) {
329  $plugin->attributesAccess[$attr]->fillLdapValue($this->attrs);
330  }
331  }
332  unset($plugin);
333  foreach ($this->tabObject->by_object as $class => &$plugin) {
334  if (!isset($this->attributes[$class])) {
335  continue;
336  }
337  foreach ($this->attributes[$class] as $attr) {
338  $plugin->attributesAccess[$attr]->fillLdapValueHook($this->attrs);
339  }
340  }
341  unset($plugin);
342  foreach ($this->attrs as &$array) {
343  if (!is_array($array)) {
344  $array = [$array];
345  }
346  if (!isset($array['count'])) {
347  $array['count'] = count($array);
348  }
349  }
350  unset($array);
351 
352  $ui = get_userinfo();
353  $specialAttrs = [];
354  foreach (static::$uiSpecialAttributes as $attr) {
355  $specialAttrs['caller'.strtoupper($attr)] = $ui->$attr;
356  }
357  $this->attrs = templateHandling::parseArray($this->attrs, $specialAttrs, $targetdn);
358  $this->tabObject->adapt_from_template($this->attrs, array_merge([], ...array_values($this->attributes)));
359 
360  $this->applied = TRUE;
361  return $this->tabObject;
362  }
363 }
Class for applying a template.
get_template_path($filename='', $plugin=FALSE, $path='')
Return themed path for specified base file.
Definition: functions.inc:174
This interface should be implemented by all dialog classes in FusionDirectory.
static parseArray(array $attrs, array $specialAttrs, $target=NULL)
Parse template masks in an array.
setValues($values, $ldapFormat=FALSE)
Set values.
& get_userinfo()
Return the current userinfo object.
Definition: functions.inc:312
reset()
Used when you need to re-apply the same template with different values.
render()
Render the dialog and returns the HTML code.
static fetch($dn)
Fetch a template from LDAP and returns its attributes and dependencies information.
& get_smarty()
Get global smarty object.
Definition: functions.inc:324
update()
Update state and return FALSE if the dialog was closed.
static open(string $dn, string $type)
Create the tab object for the given dn.
deserialize($values)
Deserialize values into the template.
static neededAttrs(array &$attrs, array $flatdepends)
Return attrs needed before applying template.
dn2base($dn, $ou=NULL)
Return the base of a given DN.
Definition: functions.inc:614
serialize()
Serialize this template for webservice.
getValues()
Get all attribute values.
readPost()
Interpret POST content.