FusionDirectory
class_CopyPasteHandler.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) 2003-2010 Cajus Pollmeier
5  Copyright (C) 2011-2017 FusionDirectory
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
31 {
32  var $current = FALSE;
33 
37  protected $objectList = [];
41  protected $queue = [];
42 
46  protected $lastdn = '';
47 
48  protected $disallowed_objects = [];
49  protected $objects_to_fix = [];
50  protected $clean_objects = [];
51  protected $require_update = FALSE;
52 
56  function __construct ()
57  {
58  }
59 
73  function add_to_queue ($dn, $action, $type)
74  {
75  logging::debug(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $dn, 'add_to_queue');
76 
77  if (!in_array($action, ['cut','copy'])) {
78  trigger_error(sprintf('Specified action "%s" does not exists for copy & paste.', $action));
79  return FALSE;
80  }
81 
82  $tmp = [];
83 
84  $tmp['method'] = $action;
85  $tmp['dn'] = $dn;
86  $tmp['type'] = $type;
87 
88  $infos = objects::infos($type);
89  $tmp['aclCategory'] = $infos['aclCategory'];
90  $tmp['mainTab'] = $infos['mainTab'];
91  $tmp['parent'] = NULL;
92 
93  $this->queue[] = $tmp;
94  if ($action == 'copy') {
95  $this->objectList[] = $tmp;
96  }
97  $this->require_update = TRUE;
98 
99  return TRUE;
100  }
101 
102 
108  function cleanup_queue ()
109  {
110  $this->current = FALSE;
111  $this->require_update = TRUE;
112  $this->queue = [];
113  $this->objectList = [];
114  }
115 
119  function resetPaste ()
120  {
121  $this->current = FALSE;
122  $this->require_update = TRUE;
123  $this->queue = $this->objectList;
124  }
125 
129  function entries_queued ()
130  {
131  return ((count($this->queue) > 0) || ($this->current !== FALSE));
132  }
133 
137  protected function load_entry_from_ldap ($entry)
138  {
139  logging::debug(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $entry['dn'], 'load_entry_from_ldap');
140  if (!isset($entry['tab_class']) && !isset($entry['type'])) {
141  return [];
142  }
143 
144  $entry['object'] = objects::open($entry['dn'], $entry['type']);
145 
146  if ($entry['parent'] !== NULL) {
147  $entry['object']->parent = $entry['parent'];
148  }
149 
150  if ($entry['method'] == 'copy') {
151  $entry['object']->resetCopyInfos();
152  }
153 
154  logging::log('copy', $entry['method'], $entry['dn'], [], '');
155 
156  $entry['object']->resetBase();
157 
158  return $entry;
159  }
160 
161  public function update (): bool
162  {
163  $ui = get_userinfo();
164 
165  /* Check which entries can be pasted directly.
166  * Create a list of all entries that can be pasted directly.
167  */
168  if ($this->require_update) {
169  $this->clean_objects = [];
170  $this->objects_to_fix = [];
171  $this->disallowed_objects = [];
172 
173  /* Put each queued object in one of the above arrays */
174  foreach ($this->queue as $key => $entry) {
175 
176  /* Update entries on demand */
177  if (!isset($entry['object'])) {
178  $entry = $this->load_entry_from_ldap($entry);
179  $this->queue[$key] = $entry;
180  }
181 
182  /* Retrieve ACL infos */
183  $copy_acl = $ui->is_copyable($entry['dn'], $entry['aclCategory']);
184  $cut_acl = $ui->is_cutable($entry['dn'], $entry['aclCategory'], $entry['mainTab']);
185 
186  /* Check permissions */
187  if ((($entry['method'] == 'copy') && !$copy_acl)
188  || (($entry['method'] == 'cut') && !$cut_acl)) {
189  $this->disallowed_objects[$key] = $entry;
190  } else {
191  $this->clean_objects[$key] = $entry;
192  }
193  }
194  if (count($this->disallowed_objects)) {
195  $dns = [];
196  foreach ($this->disallowed_objects as $entry) {
197  $dns[] = $entry['dn'];
198  }
200  $error->display();
201  }
202  $this->require_update = FALSE;
203  }
204 
205  /* Save objects that can be pasted directly */
206  if (count($this->clean_objects)) {
207  foreach ($this->clean_objects as $key => $entry) {
208  $this->current = $entry;
209  $errors = $this->current['object']->save();
210 
211  if (empty($errors)) {
212  $this->current_saved();
213  /* Remove from queue -> avoid saving twice */
214  unset($this->queue[$key]);
215  } else {
216  $this->objects_to_fix[$key] = $entry;
217  }
218  unset($this->clean_objects[$key]);
219  }
220  $this->current = FALSE;
221  }
222 
223  /* Save edited entry and force loading new one */
224  if (isset($this->current['object'])) {
225  $dialogWasOpened = $this->current['object']->dialogOpened();
226  $this->current['object']->readPost();
227  $this->current['object']->update();
228  /* Save current object if edition is finished */
229  if (!$dialogWasOpened && !$this->current['object']->dialogOpened() && isset($_POST['edit_finish'])) {
230  $errors = $this->current['object']->save();
231 
232  if (empty($errors)) {
233  $this->current_saved();
234  } else {
235  msg_dialog::displayChecks($errors);
236  }
237  }
238  }
239 
240  return TRUE;
241  }
242 
247  public function render (): string
248  {
249  /* Display a list of all pastable entries */
250  if ($this->current || count($this->objects_to_fix)) {
251  if (!$this->current) {
252  $key = key($this->objects_to_fix);
253  if ($key !== NULL) {
254  $this->current = $this->objects_to_fix[$key];
255  unset($this->objects_to_fix[$key]);
256  unset($this->queue[$key]);
257  }
258  }
259  if ($this->current) {
260  $display = $this->current['object']->render();
261  if (!$this->current['object']->dialogOpened()) {
262  // Display ok, (apply) and cancel buttons
263  $display .= '<p class="plugbottom">'."\n";
264  $display .= '<input type="submit" name="edit_finish" style="width:80px" value="'.msgPool::okButton().'"/>'."\n";
265  $display .= "&nbsp;\n";
266  $display .= '<input type="submit" formnovalidate="formnovalidate" name="abort_current_cut-copy_operation" value="'.msgPool::cancelButton().'"/>'."\n";
267  $display .= '<input type="submit" formnovalidate="formnovalidate" name="abort_all_cut-copy_operations" value="'._('Cancel all').'"/>'."\n";
268  $display .= '</p>';
269  }
270  return $display;
271  }
272  }
273  return '';
274  }
275 
276  private function current_saved ()
277  {
278  $this->lastdn = $this->current['object']->dn;
279  logging::log('copy', 'paste', $this->lastdn);
280  $this->handleReferences();
281  $this->current = FALSE;
282  }
283 
289  function last_entry ()
290  {
291  return $this->lastdn;
292  }
293 
297  public function readPost ()
298  {
299  if (isset($_POST['abort_current_cut-copy_operation'])) {
300  $this->current = FALSE;
301  }
302 
303  if (isset($_POST['abort_all_cut-copy_operations'])) {
304  $this->cleanup_queue();
305  $this->current = FALSE;
306  }
307  }
308 
309  function handleReferences ()
310  {
311  $dst_dn = $this->current['object']->dn;
312  $src_dn = $this->current['dn'];
313 
314  $this->current['object']->getBaseObject()->handleForeignKeys(
315  $src_dn,
316  $dst_dn,
317  ($this->current['method'] == 'cut' ? 'move' : 'copy')
318  );
319  }
320 
326  function generatePasteIcon ()
327  {
328  $Copy_Paste = "&nbsp;<img class='center' src='images/lists/seperator.png' alt='' height='16' width='1'>&nbsp;";
329  if ($this->entries_queued()) {
330  $Copy_Paste .= "<input type='image' name='editPaste' class='center'
331  src='geticon.php?context=actions&amp;icon=edit-paste&amp;size=16' alt='"._("Paste")."'>&nbsp;";
332  } else {
333  $Copy_Paste .= "<img class='center' src='geticon.php?context=actions&amp;icon=edit-paste&amp;size=16&amp;disabled=1' alt=\""._("Cannot paste")."\">&nbsp;";
334  }
335  return $Copy_Paste;
336  }
337 }
add_to_queue($dn, $action, $type)
Entry entry to Copy & Paste queue. A Queue entry is represented as follows. array[&#39;method&#39;] - &#39;copy&#39; or &#39;...
cleanup_queue()
This removes all objects from queue. Remove hdd dumps of current entries too. Remove entries older th...
entries_queued()
Check if there are still entries the object queue.
update()
Update state and return FALSE if the dialog was closed.
generatePasteIcon()
Generate the paste icon for headpages.
This interface should be implemented by all dialog classes in FusionDirectory.
$objectList
This array contains all dns of the currently copied objects.
resetPaste()
This resets the queue to allow pasting again.
load_entry_from_ldap($entry)
Paste one entry from LDAP.
& get_userinfo()
Return the current userinfo object.
Definition: functions.inc:312
This class contains all function to copy and paste.
__construct()
Create CP handler.
static log(string $action, string $objecttype, string $object, array $changes=[], string $result='')
logging method
last_entry()
Get the last endited entry.
static permCreate($name='')
Display that we have no permission to create an object.
readPost()
Save new values posted by copy & paste dialog.
$lastdn
The dn of the last edited object.
static open(string $dn, string $type)
Create the tab object for the given dn.
static debug(int $level, int $line, string $function, string $file, $data, string $info='')
Debug output method.
render()
Displays a dialog which allows the user to fix all dependencies of this object. Create unique names...
$queue
This array contains all remaining objects to paste.