foldershare-8.x-1.2/src/Entity/FolderShareTraits/OperationDuplicateTrait.php

src/Entity/FolderShareTraits/OperationDuplicateTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<?php
 
namespace Drupal\foldershare\Entity\FolderShareTraits;
 
use Drupal\Core\Database\Database;
 
/**
 * Duplicate FolderShare entities.
 *
 * This trait includes methods to duplicate FolderShare entities into
 * the same parent folder or the user's root list.
 *
 * <B>Internal trait</B>
 * This trait is internal to the FolderShare module and used to define
 * features of the FolderShare entity class. It is a mechanism to group
 * functionality to improve code management.
 *
 * @ingroup foldershare
 */
trait OperationDuplicateTrait {
 
  /*---------------------------------------------------------------------
   *
   * Duplicate.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function createDuplicate() {
    // This method's actions are slightly in conflict with the base Entity
    // class's definition for the createDuplicate() method.
    //
    // createDuplicate() is supposed to:
    // - Create and return a clone of $this with all fields filled in,
    //   except for an ID, so that saving it will insert the new entity
    //   into the storage system.
    //
    // This is not practical for FolderShare, where duplicating the entity
    // also needs to duplicate its children. And those children need to
    // point back to the parent, so the parent has to have been fully
    // created first and have an entity ID.
    //
    // Therefore, this entity's implementation of createDuplicate() creates
    // AND saves the entity, thereby creating the ID and commiting the new
    // entity to storage. If the caller calls save() again on the returned
    // entity, this won't hurt anything. But if they think that skipping a
    // call to save() will avoid saving the entity, that won't be true.
    return $this->duplicate();
  }
 
  /**
   * {@inheritdoc}
   */
  public function duplicate() {
    if ($this->isRootItem() === TRUE) {
      // Create a copy in the user's root list and allow renaming so that
      // the duplicate has a unique name.
      return $this->copyToRoot('', TRUE);
    }
    else {
      // Create a copy in the parent folder and allow renaming so that
      // the duplicate has a unique name.
      $parent = $this->getParentFolder();
      if ($parent === NULL) {
        // There is no parent but it isn't a root item? Corrupted.
        return NULL;
      }
 
      return $this->copyToFolder($parent, '', TRUE);
    }
  }
 
  /**
   * Duplicates multiple items in to the same parents or the user's root list.
   *
   * Each of the indicated items is duplicated and added to their parents.
   * If an item is a folder, the folder's descendants are duplicated as well.
   *
   * <B>Background duplicate</B>
   * File copies occur immediately, but folder copies schedule background
   * tasks to traverse the folder tree and update descendants. This will
   * delay completion of the copy to a time in the future that depends upon
   * the size of the folder tree being copied and server load.
   *
   * <B>Process locks</B>
   * This method locks the root folder tree, or the user's root list, while
   * duplicating items into the same folder tree or root list.
   *
   * <B>Post-operation hooks</B>
   * This method calls the "hook_foldershare_post_operation_copy" hook for
   * each item copied.
   *
   * <B>Activity log</B>
   * This method posts a log message after each item is duplicated.
   *
   * @param int[] $ids
   *   An array of integer FolderShare entity IDs to duplicate. Invalid IDs
   *   are silently skipped.
   *
   * @throws \Drupal\foldershare\Entity\Exception\LockException
   *   Throws an exception if an access lock could not be acquired.
   * @throws \Drupal\foldershare\Entity\Exception\ValidationException
   *   Throws an exception if a unique name cannot be created for the
   *   duplicate.
   * @throws \Drupal\foldershare\Entity\Exception\SystemException
   *   For files, throws an exception if a serious system error occurs while
   *   duplicating the underlying local file. System errors may indicate a
   *   file system has become unreadable/unwritable, is full, or is offline.
   *
   * @see ::duplicate()
   * @see ::copyToFolderMultiple()
   * @see ::copyToRootMultiple()
   */
  public static function duplicateMultiple(array $ids) {
    if (empty($ids) === TRUE) {
      // Nothing to duplicate.
      return;
    }
 
    $connection = Database::getConnection();
 
    //
    // Group ids by location.
    // ----------------------
    // Duplication is a copy. If an ID refers to a root-level item, then
    // we'll invoke copyToRoot() on it to copy into the root. But if an ID
    // refers to a folder-level item, then we'll invoke copyToFolder()
    // with the appropriate folder as the destination.
    //
    // So we need to sort by where an entity is, and thus where to put the
    // duplicate.
    $groups = [];
    foreach ($ids as $id) {
      // Query the database to get the root and parent IDs rather than
      // load the entire entity. This saves time and memory.
      $select = $connection->select(self::BASE_TABLE, 'fs');
      $select->addField('fs', 'rootid', 'rootid');
      $select->addField('fs', 'parentid', 'parentid');
      $select->condition('id', $id, '=');
      $results = $select->execute()->fetchAll();
 
      if (count($results) === 0) {
        // The item does not exist.
        continue;
      }
 
      $rootId = $results[0]->rootid;
      $parentId = $results[0]->parentid;
 
      if ($rootId === NULL) {
        // The item is at the root level. Add it to a group of
        // root level items.
        $groups['root'][] = (int) $id;
      }
      else {
        // The item is at the folder level. Add it to a group
        // with the same parent folder.
        $groups[(int) $parentId][] = (int) $id;
      }
    }
 
    //
    // Duplicate each group.
    // ---------------------
    // Run through the groups and initiate copies into the appropriate
    // destination. Allow the name to be changed to make the copy unique.
    if (empty($groups['root']) === FALSE) {
      self::copyToRootMultiple($groups['root'], TRUE);
      unset($groups['root']);
    }
 
    foreach ($groups as $parentId => $group) {
      if (empty($group) === TRUE) {
        // Nothing to copy.
        continue;
      }
 
      $parent = self::load($parentId);
      if ($parent === NULL) {
        // The parent does not exist. File system is corrupted.
        continue;
      }
 
      self::copyToFolderMultiple($group, $parent, TRUE);
      unset($parent);
    }
  }
 
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc