Updates category tree, returns true on success.

@return bool
501119
protected function _update()
    {
        $this->setUpdateSeo(true);
        $this->_setUpdateSeoOnFieldChange('oxtitle');

        // Function is called from inside a transaction in Category::save (see ESDEV-3804 and ESDEV-3822).
        // No need to explicitly force master here.
        $database = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
        $sOldParentID = $database->getOne("select oxparentid from oxcategories where oxid = " . $database->quote($this->getId()));

        if ($this->_blIsSeoObject && $this->isAdmin()) {
            \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Application\Model\SeoEncoderCategory::class)->markRelatedAsExpired($this);
        }

        $blRes = parent::_update();

        // #872C - need to update category tree oxleft and oxright values (nested sets),
        // then sub trees are moved inside one root, or to another root.
        // this is done in 3 basic steps
        // 1. increase oxleft and oxright values of target root tree by $iTreeSize, where oxleft>=$iMoveAfter , oxright>=$iMoveAfter
        // 2. modify current subtree, we want to move by adding $iDelta to it's oxleft and oxright,  where oxleft>=$sOldParentLeft and oxright<=$sOldParentRight values,
        //    in this step we also modify rootid's if they were changed
        // 3. decreasing oxleft and oxright values of current root tree, where oxleft >= $sOldParentRight+1 , oxright >= $sOldParentRight+1

        // did we change position in tree ?
        if ($this->oxcategories__oxparentid->value != $sOldParentID) {
            $sOldParentLeft = $this->oxcategories__oxleft->value;
            $sOldParentRight = $this->oxcategories__oxright->value;

            $iTreeSize = $sOldParentRight - $sOldParentLeft + 1;

            $sNewRootID = $database->getOne("select oxrootid from oxcategories where oxid = " . $database->quote($this->oxcategories__oxparentid->value));

            //If empty rootID, we set it to categorys oxid
            if ($sNewRootID == "") {
                //echo "<br>* ) Creating new root tree ( {$this->_sOXID} )";
                $sNewRootID = $this->getId();
            }
            $sNewParentLeft = $database->getOne("select oxleft from oxcategories where oxid = " . $database->quote($this->oxcategories__oxparentid->value));

            //if(!$sNewParentLeft){
            //the current node has become root node, (oxrootid == "oxrootid")
            //    $sNewParentLeft = 0;
            //}

            $iMoveAfter = $sNewParentLeft + 1;

            //New parentid can not be set to it's child
            if ($sNewParentLeft > $sOldParentLeft && $sNewParentLeft < $sOldParentRight && $this->oxcategories__oxrootid->value == $sNewRootID) {
                //echo "<br>* ) Can't asign category to it's child";

                //Restoring old parentid, stoping further actions
                $sRestoreOld = "UPDATE oxcategories SET OXPARENTID = " . $database->quote($sOldParentID) . " WHERE oxid = " . $database->quote($this->getId());
                $database->execute($sRestoreOld);

                return false;
            }

            //Old parent will be shifted too, if it is in the same tree
            if ($sOldParentLeft > $iMoveAfter && $this->oxcategories__oxrootid->value == $sNewRootID) {
                $sOldParentLeft += $iTreeSize;
                $sOldParentRight += $iTreeSize;
            }

            $iDelta = $iMoveAfter - $sOldParentLeft;

            //echo "Size=$iTreeSize, NewStart=$iMoveAfter, delta=$iDelta";

            $sAddOld = " and oxshopid = '" . $this->getShopId() . "' and OXROOTID = " . $database->quote($this->oxcategories__oxrootid->value) . ";";
            $sAddNew = " and oxshopid = '" . $this->getShopId() . "' and OXROOTID = " . $database->quote($sNewRootID) . ";";

            //Updating everything after new position
            $database->execute("UPDATE oxcategories SET OXLEFT = (OXLEFT + " . $iTreeSize . ") WHERE OXLEFT >= " . $iMoveAfter . $sAddNew);
            $database->execute("UPDATE oxcategories SET OXRIGHT = (OXRIGHT + " . $iTreeSize . ") WHERE OXRIGHT >= " . $iMoveAfter . $sAddNew);
            //echo "<br>1.) + $iTreeSize, >= $iMoveAfter";

            $sChangeRootID = "";
            if ($this->oxcategories__oxrootid->value != $sNewRootID) {
                //echo "<br>* ) changing root IDs ( {$this->oxcategories__oxrootid->value} -> {$sNewRootID} )";
                $sChangeRootID = ", OXROOTID=" . $database->quote($sNewRootID);
            }

            //Updating subtree
            $database->execute("UPDATE oxcategories SET OXLEFT = (OXLEFT + " . $iDelta . "), OXRIGHT = (OXRIGHT + " . $iDelta . ") " . $sChangeRootID . " WHERE OXLEFT >= " . $sOldParentLeft . " AND OXRIGHT <= " . $sOldParentRight . $sAddOld);
            //echo "<br>2.) + $iDelta, >= $sOldParentLeft and <= $sOldParentRight";

            //Updating everything after old position
            $database->execute("UPDATE oxcategories SET OXLEFT = (OXLEFT - " . $iTreeSize . ") WHERE OXLEFT >=   " . ($sOldParentRight + 1) . $sAddOld);
            $database->execute("UPDATE oxcategories SET OXRIGHT = (OXRIGHT - " . $iTreeSize . ") WHERE OXRIGHT >=   " . ($sOldParentRight + 1) . $sAddOld);
            //echo "<br>3.) - $iTreeSize, >= ".($sOldParentRight+1);
        }

        if ($blRes && $this->_blIsSeoObject && $this->isAdmin()) {
            \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Application\Model\SeoEncoderCategory::class)->markRelatedAsExpired($this);
        }

        return $blRes;
    }
514827
public function cmdUpdateCategoryGroup()
    {
        $params = $this->getParam();

        if (empty($params[0]) || count($params) < 2) {
            $this->errorAndExit($this->text('Invalid command'));
        }

        if (!is_numeric($params[0])) {
            $this->errorAndExit($this->text('Invalid argument'));
        }

        $this->setSubmitted(null, $params);
        $this->setSubmitted('update', $params[0]);
        $this->validateComponent('category_group');

        $this->updateCategoryGroup($params[0]);
        $this->output();
    }
711022
public static function update_categories($categories) {
        global $DB;

        // Validate parameters.
        $params = self::validate_parameters(self::update_categories_parameters(), array('categories' => $categories));

        $transaction = $DB->start_delegated_transaction();

        foreach ($params['categories'] as $cat) {
            $category = core_course_category::get($cat['id']);

            $categorycontext = context_coursecat::instance($cat['id']);
            self::validate_context($categorycontext);
            require_capability('moodle/category:manage', $categorycontext);

            // this will throw an exception if descriptionformat is not valid
            external_validate_format($cat['descriptionformat']);

            $category->update($cat);
        }

        $transaction->allow_commit();
    }
1138076
public function commit()
    {
        list($old, $new) = $this->generateRollback();
        $updates = $this->generateUpdates();
        $updates = $this->combineUpdates($updates);
        usort($updates, array($this, 'sortUpdates'));

        foreach ($updates as $update) {
            // apply update to cache & receive a simple bool to indicate
            // success (true) or failure (false)
            $success = call_user_func_array($update[1], $update[2]);
            if ($success === false) {
                $this->rollback($old, $new);

                return false;
            }
        }

        $this->clear();

        return true;
    }
855912
protected function syncAdditionalCategoryList()
    {
        if ($this->arAdditionalCategoryList === null) {
            return;
        }

        $this->obModel->additional_category()->sync($this->arAdditionalCategoryList);
    }
96874
public function update(CategoryRequest $request, Category $category)
    {
        $this->repository->update($category, $request->all());
        
        return redirect()->route('admin.category.index');
    }
107317
public function syncCategories() {
    $this->output->writeln(dt('Synchronizing all commerce categories, please wait...'));
    $response = $this->acmCategoryManager->synchronizeTree($this->categoryVid);

    // We trigger delete only if there is any term update/create.
    // So if API does not return anything, we don't delete all the categories.
    if (!empty($response['created']) || !empty($response['updated'])) {
      // Get all category terms with commerce id.
      $orphan_categories = $this->acmCategoryManager->getOrphanCategories($response);

      // If there are categories to delete.
      if (!empty($orphan_categories)) {
        // Show `tid + cat name + commerce id` for review.
        $this->io()->table([
          dt('Category Id'),
          dt('Category Name'),
          dt('Category Commerce Id'),
        ], $orphan_categories);

        // Confirmation to delete old categories.
        if ($this->io()->confirm(dt('Are you sure you want to clean these old categories'), FALSE)) {

          // Allow other modules to skipping the deleting of terms.
          $this->moduleHandler->alter('acm_sku_sync_categories_delete', $orphan_categories);

          foreach ($orphan_categories as $tid => $rs) {
            $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid);
            if ($term instanceof TermInterface) {
              // Delete the term.
              $term->delete();
            }
          }
        }
      }
    }
    else {
      $this->logger->notice(dt('Not cleaning(deleting) old terms as there is no term update/create.'));
    }

    $this->output->writeln(dt('Done.'));
  }
876371
public function ApplyUpdates() {
      if (!C('Vanilla.NestedCategoriesUpdate')) {
         // Add new columns
         $Construct = Gdn::Database()->Structure();
         $Construct->Table('Category')
            ->Column('TreeLeft', 'int', TRUE)
            ->Column('TreeRight', 'int', TRUE)
            ->Column('Depth', 'int', TRUE)
            ->Column('CountComments', 'int', '0')
            ->Column('LastCommentID', 'int', TRUE)
            ->Set(0, 0);

         // Insert the root node
         if ($this->SQL->GetWhere('Category', array('CategoryID' => -1))->NumRows() == 0)
            $this->SQL->Insert('Category', array('CategoryID' => -1, 'TreeLeft' => 1, 'TreeRight' => 4, 'Depth' => 0, 'InsertUserID' => 1, 'UpdateUserID' => 1, 'DateInserted' => Gdn_Format::ToDateTime(), 'DateUpdated' => Gdn_Format::ToDateTime(), 'Name' => 'Root', 'UrlCode' => '', 'Description' => 'Root of category tree. Users should never see this.'));
         
         // Build up the TreeLeft & TreeRight values.
         $this->RebuildTree();
         
         SaveToConfig('Vanilla.NestedCategoriesUpdate', 1);
      }
   }
604167
public function update(Category $category, UpdateCategoryRequest $request)
    {
        $this->category->update($category, $request->all());

        return redirect()->route('admin.product.category.index')
            ->withSuccess(trans('core::core.messages.resource updated', ['name' => trans('product::categories.title.categories')]));
    }
1083831
protected function updateCategories(Collection $data)
	{
		$ids = explode(',', $this->preferences['product_categories']);

		$categories = Collection::make($ids)
			->merge($data)
			->unique()
			->take(self::MAX_TAGS)
			->implode(',');

		$this->preferences['product_categories'] = trim($categories, ',');
	}
649960
protected function setDataCategoriesEditCategory()
    {
        $category_id = $this->getData('category.category_id');

        if (isset($category_id)) {

            $category_group_id = $this->getData('category_group.category_group_id');

            $options = array(
                'parent_id' => $category_id,
                'category_group_id' => $category_group_id
            );

            $children = $this->category->getTree($options);

            $exclude = array($category_id);
            foreach ($children as $child) {
                $exclude[] = $child['category_id'];
            }

            $categories = $this->getData('categories');
            $modified = array_diff_key($categories, array_flip($exclude));
            $this->setData('categories', $modified);
        }
    }
1371005
public function sort_categories() {
        $this->attach_nodes_to_categories();
        $tempcategories = array();
        foreach ($this->categories as $category) {
            $after = $category->after;
            if ($after == null) {
                // Can go anywhere in the tree.
                $category->sort_nodes();
                $tempcategories = array_merge($tempcategories, array($category->name => $category),
                        $this->find_categories_after($category));
            }
        }
        if (count($tempcategories) !== count($this->categories)) {
            // Orphan categories found.
            throw new \coding_exception('Some of the categories specified contains invalid \'after\' property');
        }
        $this->categories = $tempcategories;
    }
1134604
public function updateCategoryTree($blVerbose = true, $sShopID = null)
    {
        // Only called from admin and admin mode reads from master (see ESDEV-3804 and ESDEV-3822).
        $database = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
        $database->startTransaction();

        try {
            $sWhere = $this->getInitialUpdateCategoryTreeCondition($blVerbose);

            $database->execute("update oxcategories set oxleft = 0, oxright = 0 where $sWhere");
            $database->execute("update oxcategories set oxleft = 1, oxright = 2 where oxparentid = 'oxrootid' and $sWhere");

            // Get all root categories
            $rs = $database->select("select oxid, oxtitle from oxcategories where oxparentid = 'oxrootid' and $sWhere order by oxsort", false);
            if ($rs != false && $rs->count() > 0) {
                while (!$rs->EOF) {
                    $this->_aUpdateInfo[] = "<b>Processing : " . $rs->fields[1] . "</b>(" . $rs->fields[0] . ")<br>";
                    if ($blVerbose) {
                        echo next($this->_aUpdateInfo);
                    }
                    $oxRootId = $rs->fields[0];

                    $this->_updateNodes($oxRootId, true, $oxRootId);
                    $rs->fetchRow();
                }
            }
            $database->commitTransaction();
        } catch (Exception $exception) {
            $database->rollbackTransaction();
            throw $exception;
        }

        $this->onUpdateCategoryTree();
    }
369132
public function update(DocumentCategory $category)
    {
        $attributes = request()->validate(DocumentCategory::$rules, DocumentCategory::$messages);

        $category = $this->updateEntry($category, $attributes);

        return redirect_to_resource();
    }
610541
public function getEntityByCategory($root, $category)
    {
        if (isset($this->categoriesWithRoots[$root][$category])) {
            return $this->categoriesWithRoots[$root][$category];
        }

        if (isset($this->newCategory[$root][$category])) {
            return $this->newCategory[$root][$category];
        }

        return false;
    }
755163
public function updateDepth()
    {
        $parent = $this->ParentComment();
        if ($parent && $parent->exists()) {
            $parent->updateDepth();
            $this->Depth = $parent->Depth + 1;
        } else {
            $this->Depth = 1;
        }
    }
563946
public function updateUserViewedCategory($categoryId = '')
    {
        $sessionUserViewedCategoryId = self::SESSION_ID_USER_VIEW_TOTAL_POST_BY_CATEGORY_FROM_SESSION . $categoryId;
        $this->logger->debug(__FUNCTION__, '$sessionUserViewedCategoryId => ' . json_encode($sessionUserViewedCategoryId));
        $checkSessionUserViewedCategoryValue = $this->hasSessionData($sessionUserViewedCategoryId);
        $this->logger->debug(__FUNCTION__, '$checkSessionUserViewedCategoryValue => ' . json_encode($checkSessionUserViewedCategoryValue));
        if ($checkSessionUserViewedCategoryValue === TRUE) {
            $currentSessionUserViewedCategoryValue = $this->getSessionData($sessionUserViewedCategoryId);
            $this->logger->debug(__FUNCTION__, '$currentSessionUserViewedCategoryValue => ' . json_encode($currentSessionUserViewedCategoryValue));
            if (is_numeric($currentSessionUserViewedCategoryValue)) {
                $viewValue = $currentSessionUserViewedCategoryValue + 1;
            } else {
                $viewValue = 1;
            }
            $this->logger->debug(__FUNCTION__, 'Update Total View Value: ' . $viewValue);
            $this->saveSessionData($sessionUserViewedCategoryId, $viewValue);
        } else {
            $this->saveSessionData($sessionUserViewedCategoryId, 1);
        }
    }