/** * Creates data provider instance with search query applied * * @param array $params * * @return ActiveDataProvider */ public function search($params) { $query = CmsHierarchyItem::find(); $dataProvider = new ActiveDataProvider(['query' => $query]); if (!($this->load($params) && $this->validate())) { return $dataProvider; } $query->andFilterWhere(['id' => $this->id, 'parent_id' => $this->parent_id, 'position' => $this->position, 'display_state' => $this->display_state]); return $dataProvider; }
/** * change position of an hierarchy item and reset following sibling positions accordingly * @menuLabel __HIDDEN__ * @menuIcon <span class="glyphicon glyphicon-list-alt"></span> * @functionalRight cmsBackendWrite * * @param integer $hierarchyItemId * the item id of the hierarchy item position to set the new position value for * @param integer $newPosition * the position value. Values must equal or larger than 1 (0 is not allowed) * @return string json encoded, associcative result array */ public function actionSetItemPositionWithinSiblingsJson($hierarchyItemId = -1, $newPosition = 0, $overwritePosition = false) { $result = []; $result['result'] = 'failed'; $result['success'] = false; $hierarchyItemId = intval($hierarchyItemId); $newPosition = intval($newPosition); $hierarchyItem = CmsHierarchyItem::findOne($hierarchyItemId); if ($hierarchyItemId == 0 || !$hierarchyItem) { $result['message'] = 'invalid or no hierarchy item id given'; } else { if ($hierarchyItem->id == 0) { $result['message'] = 'the root hierarchy items position value cannot be modified'; } else { if ($newPosition <= 0) { $result['message'] = 'invalid position value given, must equal to or larger than 1'; } else { if ($hierarchyItem->position == $newPosition && !$overwritePosition) { $result['message'] = 'new item position is equal to old position, no changes needed'; } else { // parameters are fine so far, get all siblings of item to change position for $hierarchyItemSiblings = CmsHierarchyItem::find()->where(['parent_id' => $hierarchyItem->parent_id])->orderby('position ASC')->all(); $newItemOrder = []; // fill array with all items, except the one to move foreach ($hierarchyItemSiblings as $item) { if ($item->id != intval($hierarchyItem->id)) { $newItemOrder[] = $item; } } // now splice in the new one at the desired position array_splice($newItemOrder, $newPosition - 1, 0, [$hierarchyItem]); $returnArray = []; $allOk = true; // update items and fill return array for ($i = 0; $i < count($newItemOrder); $i++) { $item = $newItemOrder[$i]; $updated = false; // check if db item needs update if ($item->position != $i + 1) { $item->position = $i + 1; $updated = $item->save(); if (!$updated) { $allOk = false; } } $returnItem = new BasicHierarchyItem($item); $returnItem->updated = $updated; $returnArray[] = $returnItem; } $result['result'] = 'success'; $result['success'] = $allOk; $result['message'] = 'new item positions set'; $result['items'] = $returnArray; } } } } Yii::$app->response->format = \yii\web\Response::FORMAT_RAW; $headers = Yii::$app->response->headers; $headers->add('Content-Type', 'application/json; charset=utf-8'); Yii::$app->response->charset = 'UTF-8'; return json_encode($result, JSON_PRETTY_PRINT); }
/** * Fix the position values of all child items for the given parent id. * This should be called once a new item is inserted amongst other siblings or just to perform an integrity check and avoid duplicate position values amongst siblings. * This function is quite expensive due to the sql calls (espcially in recusrion mode) so it must not be used in often called functions. * * @param unknown $parentItemId * the item id to get the children for an set the position values * @param boolean $recurseTree * recurse into the subtree structure * @param unknown $updateCounter * @param unknown $failedUpdateCounter * @param unknown $checkedItems */ public static function fixItemPositionsForChildren($parentItemId, &$updateCounter, &$failedUpdateCounter, &$checkedItems, $recurseTree = false) { $childItems = CmsHierarchyItem::find()->where(['parent_id' => $parentItemId])->orderby('position ASC')->all(); foreach ($childItems as $arrayIndex => $item) { $checkedItems++; $positionValue = $arrayIndex + 1; if ($item->position != $positionValue) { $item->position = $positionValue; if ($item->save()) { $updateCounter++; } else { $failedUpdateCounter++; } } if ($recurseTree) { SettingsAndMaintenanceController::fixItemPositionsForChildren($item->id, $updateCounter, $failedUpdateCounter, $checkedItems, true); } } }