foldershare-8.x-1.2/src/Entity/FolderShareTraits/GetSetRootTrait.php
src/Entity/FolderShareTraits/GetSetRootTrait.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 | <?php namespace Drupal\foldershare\Entity\FolderShareTraits; use Drupal\Core\Database\Database; use Drupal\foldershare\FolderShareInterface; /** * Get/set FolderShare entity root fields. * * This trait includes get and set methods for FolderShare entity * root fields. * * <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 GetSetRootTrait { /*--------------------------------------------------------------------- * * Root field. * *---------------------------------------------------------------------*/ /** * Clears the root ID. * * <B>This method is internal and strictly for use by the FolderShare * module itself.</B> * * The caller must call save() for the change to take effect. * * <B>Process locks</B> * This method does not lock access. The caller should lock around changes * to the entity. * * @see ::setRootItemId() */ private function clearRootItemId() { $this ->rootid->setValue([ 'target_id' => NULL]); } /** * {@inheritdoc} */ public function getRootItem() { $id = $this ->getRootItemId(); if ( $id === (int) $this ->id()) { return $this ; } return self::load( $id ); } /** * {@inheritdoc} */ public function getRootItemId() { $rootField = $this ->rootid->getValue(); if (( empty ( $rootField ) === TRUE) || (isset( $rootField [0]) === FALSE) || ( empty ( $rootField [0]) === TRUE) || (isset( $rootField [0][ 'target_id' ]) === FALSE) || ( empty ( $rootField [0][ 'target_id' ]) === TRUE)) { // Empty. No root. // // Freshly loaded entities tend to have empty root fields for root // items. But entities during construction or after having a root // ID cleared have non-empty root fields with empty target IDs. // We need to check all of the possibilities to be sure this is a // root item. return (int) $this ->id(); } return (int) $rootField [0][ 'target_id' ]; } /** * {@inheritdoc} */ public function isRootItem() { // Root items have empty parent and root IDs. $rootField = $this ->rootid->getValue(); return ( empty ( $rootField ) === TRUE) || (isset( $rootField [0]) === FALSE) || ( empty ( $rootField [0]) === TRUE) || (isset( $rootField [0][ 'target_id' ]) === FALSE) || ( empty ( $rootField [0][ 'target_id' ]) === TRUE); } /** * Sets the root ID. * * <B>This method is internal and strictly for use by the FolderShare * module itself.</B> * * The caller must call save() for the change to take effect. * * <B>Process locks</B> * This method does not lock access. The caller should lock around changes * to the entity. * * @param int $rootId * The root ID for the new root ancestor of this item. The value is * not validated and is expected to be a valid entity ID. If the value * is FolderShareInterface::USER_ROOT_LIST, negative, or the ID of this * item, the root ID is cleared to NULL, indicating the item is in the * root list. * * @see ::clearRootItemId() * @see ::setRootItemIdRecursively() */ private function setRootItemId(int $rootId ) { if ( $rootId < 0 || (int) $this ->id() === $rootId ) { $this ->rootid->setValue([ 'target_id' => NULL]); } else { $this ->rootid->setValue([ 'target_id' => $rootId ]); } } /** * Sets the root Id on all descendants. * * <B>This method is internal and strictly for use by the FolderShare * module itself.</B> * * This method is intended for use by fsck() to fix a corrupted file * system by correcting root IDs. * * This method recurses through a folder tree, starting with the given * parent item. All descendants are given the new root ID via database * updates. * * During recursion, this method skips subfolder trees that already have * the correct root ID. It is assumed that if a parent folder has the right * root ID, the children have already been updated. This is a necessary * assumption so that repeated calls to this method during a scheduled * task will eventually find nothing more to do. * * The caller must flush all entity-dependent caches (e.g. the entity * type's storage manager caches and the render cache, at least) in * order for the changed entities to be recognized. * * @param int $parentId * The FolderShare entity ID of a parent. The parent is presumed to * already have been given the correct root ID. * @param int $rootId * The root ID to set all descendants to use. * * @see ::setRootItemId() * @see ::fsck() */ private static function setDescendantsRootItemId(int $parentId , int $rootId ) { $connection = Database::getConnection(); // Find folder children in need of updates. $query = $connection ->select(self::BASE_TABLE, 'fs' ); $query ->addField( 'fs' , 'id' , 'id' ); $query ->condition( 'parentid' , $parentId , '=' ); $query ->condition( 'kind' , FolderShareInterface::FOLDER_KIND, '=' ); $query ->condition( 'rootid' , $rootId , '<>' ); $childIds = $query ->execute()->fetchCol(0); // Recurse through all folder children. foreach ( $childIds as $childId ) { self::setDescendantsRootItemId( $childId , $rootId ); } // Update all children to the new root ID. $query = $connection ->update(self::BASE_TABLE); $query ->condition( 'parentid' , $parentId , '=' ); $query ->fields([ 'rootid' => $rootId , ]); $query ->execute(); } } |