Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZC 1.5.6: Warning notice when add/remove category links in Categories Link Manager #2311

Closed
Pan2020 opened this issue Apr 30, 2019 · 2 comments

Comments

Projects
None yet
3 participants
@Pan2020
Copy link
Contributor

commented Apr 30, 2019

When I add or remove categories on a product in Categories Link Manager, the warning appears despite there is master category on a product.

WARNING: No Master Category is set!

NoMasterCategory

This always showed up in yellow bar at the top of admin page every time after I clicked "Update Category Links" regardless whether I updated category links or not. The warning will still trigger even I went straight to click on "Update Category Links" without doing anything!

There is no PHP notice or logged generated for this warning. So I suspect this is more due to certain SQL queries on category link managers that keep triggering this...

mc12345678 added a commit to mc12345678/zc-v1-series that referenced this issue May 2, 2019

Update products_to_categories.php
Because of a change in presenting the products_to_categories page where the master category can not be deselected and the design consideration that if a store has one or more categories that a product is not to be in a category that has categories (specifically not in the root category of the store), this commit fixes zencart#2311 and ensures that a product has both a `master_categories_id` and is listed in the table `products_to_categories` if for some reason the products_to_categories page is reached for the product and the product initially did not have a `master_categories_id` set to something other than ''.

Of course, this file can not be accessed if product is in place with a master_categories_id of 0 and it is desired to link the product to other categories and possibly remove it from the master_category of the root of the store, that in other words the master_categories_id must be modified at the product's page not from this admin area and only after the product has been assigned to multiple categories.
@mc12345678

This comment has been minimized.

Copy link
Contributor

commented May 2, 2019

Can confirm that this occurs for linked product. The code section that seems involved is in admin/products_to_categories.php lines 401 through 459.

      // set the linked products master_categories_id product(s)
      for ($i = 0, $n = sizeof($_POST['categories_add']); $i < $n; $i++) {
        // is current master_categories_id in the list?
        if ($zv_check_master_categories_id == true && $_POST['categories_add'][$i] == $current_master_categories_id) {
          $zv_check_master_categories_id = true;
          // array is set above to master category
        } else {
          $zv_check_master_categories_id = false;
          $new_categories_sort_array[] = (int)$_POST['categories_add'][$i];
        }
      }
      // remove existing products_to_categories for current product
      $db->Execute("delete from " . TABLE_PRODUCTS_TO_CATEGORIES . " where products_id='" . $products_filter . "'");
      $reset_master_categories_id = '';
      $old_master_categories_id = $current_master_categories_id;
      // add products to categories in order of master_categories_id first then others
      $verify_current_category_id = false;
      for ($i = 0, $n = sizeof($new_categories_sort_array); $i < $n; $i++) {
        // is current master_categories_id in the list?
        if ($new_categories_sort_array[$i] <= 0) {
          die('I WOULD NOT ADD ' . $new_categories_sort_array[$i] . '<br>');
        } else {
          if ($current_category_id == $new_categories_sort_array[$i]) {
            $verify_current_category_id = true;
          }
          $db->Execute("INSERT INTO " . TABLE_PRODUCTS_TO_CATEGORIES . " (products_id, categories_id)
                        VALUES (" . $products_filter . ", " . (int)$new_categories_sort_array[$i] . ")");
          if ($reset_master_categories_id == '') {
            $reset_master_categories_id = $new_categories_sort_array[$i];
          }
          if ($old_master_categories_id == $new_categories_sort_array[$i]) {
            $reset_master_categories_id = $new_categories_sort_array[$i];
          }
        }
      }
      // reset master_categories_id in products table
      if ($zv_check_master_categories_id == true) {
        // make sure master_categories_id is set to current master_categories_id
        $db->Execute("UPDATE " . TABLE_PRODUCTS . "
                      SET master_categories_id = " . (int)$current_master_categories_id . "
                      WHERE products_id = " . $products_filter);
      } else {
        // reset master_categories_id to current_category_id because it was unselected
        $db->Execute("UPDATE " . TABLE_PRODUCTS . "
                      SET master_categories_id = " . (int)$reset_master_categories_id . "
                      WHERE products_id = " . $products_filter);
      }
      // recalculate price based on new master_categories_id
      zen_update_products_price_sorter($products_filter);
      if ($zv_check_master_categories_id == true) {
        $messageStack->add_session(SUCCESS_MASTER_CATEGORIES_ID, 'success');
      } else {
        $messageStack->add_session(WARNING_MASTER_CATEGORIES_ID, 'warning');
      }

There is a logic error in the overall process, though could use some clarification about what really is trying to be done along the way to ensure that the appropriate code/solution is used.

For product that are linked, this section will always set $zv_check_master_categories_id to false but will also continue to populate $new_categories_sort_array on top of $new_categories_sort_array[0] being set to the then value of $_POST['current_master_categories_id'] which may or may not be a valid/defined master_categories_id:

      for ($i = 0, $n = sizeof($_POST['categories_add']); $i < $n; $i++) {
        // is current master_categories_id in the list?
        if ($zv_check_master_categories_id == true && $_POST['categories_add'][$i] == $current_master_categories_id) {
          $zv_check_master_categories_id = true;
          // array is set above to master category
        } else {
          $zv_check_master_categories_id = false;
          $new_categories_sort_array[] = (int)$_POST['categories_add'][$i];
        }
      }

This section because we are trying to address "linked" product where there are categories off of the root of the category tree appears to try to prevent adding a product to the top of the tree as seen in the first if statement within the loop. Therefore if the original master_categories_id was 0, then this code would stop further execution at the first array element and prevent any further modification of the linkage regardless if the selections no longer included that category:

        for ($i=0, $n=sizeof($new_categories_sort_array); $i<$n; $i++) {
          // is current master_categories_id in the list?
          if ($new_categories_sort_array[$i] <= 0) {
            die('I WOULD NOT ADD ' . $new_categories_sort_array[$i] . '<br>');
          } else {
            if ($current_category_id == $new_categories_sort_array[$i]) {
              $verify_current_category_id = true;
            }
            $db->Execute("insert into " . TABLE_PRODUCTS_TO_CATEGORIES . "
                    (products_id, categories_id)
                    values (" . $products_filter . ", " . (int)$new_categories_sort_array[$i] . ")");
            if ($reset_master_categories_id == '') {
              $reset_master_categories_id = $new_categories_sort_array[$i];
            }
            if ($old_master_categories_id == $new_categories_sort_array[$i]) {
              $reset_master_categories_id = $new_categories_sort_array[$i];
            }
          }
        }

At completion of the above code, if the original products_master_id had still been selected then $verify_current_category_id would be set to true and $reset_master_categories_id would be set to the original products_master_id, if not then it would still be false as set before this loop and $reset_master_categories_id would also be equal to the original products_master_id based on being the first array element and no other element meeting the criteria of $old_master_categories_id == $new_categories_sort_array[$i].

This section:

      // reset master_categories_id in products table
      if ($zv_check_master_categories_id == true) {
        // make sure master_categories_id is set to current master_categories_id
        $db->Execute("UPDATE " . TABLE_PRODUCTS . "
                      SET master_categories_id = " . (int)$current_master_categories_id . "
                      WHERE products_id = " . $products_filter);
      } else {
        // reset master_categories_id to current_category_id because it was unselected
        $db->Execute("UPDATE " . TABLE_PRODUCTS . "
                      SET master_categories_id = " . (int)$reset_master_categories_id . "
                      WHERE products_id = " . $products_filter);
      }

for a linked product would always update the master_categories_id to be the $reset_master_categories_id which as provided above would be the original master_categories_id and not some other category that was in the selection list.

Then in a linked product situation:

      if ($zv_check_master_categories_id == true) {
        $messageStack->add_session(SUCCESS_MASTER_CATEGORIES_ID, 'success');
      } else {
        $messageStack->add_session(WARNING_MASTER_CATEGORIES_ID, 'warning');
      }

This would always display that the master categories id was not selected because in the first loop $zv_check_master_categories_id is set to false even though/if the master_categories_id for the product had been in the selection list.

And lastly and possibly the only correctly performing portion is whether to return the admin to the same category or to filter the product list to reflect the product in its current category:

      // if product was removed from current categories_id stay in same category
      if (!$verify_current_category_id) {
        zen_redirect(zen_href_link(FILENAME_PRODUCTS_TO_CATEGORIES, 'current_category_id=' . $current_category_id));
      } else {
        zen_redirect(zen_href_link(FILENAME_PRODUCTS_TO_CATEGORIES, 'products_filter=' . $products_filter . '&current_category_id=' . $current_category_id));
      }

It seems that PR: ae536f0 may have introduced a portion of the problem of above.

I've submitted PR #2325 to fix this issue even though it is beyond the proposed cut-off date of 4/30/19 as indicated in #2296.

drbyte added a commit that referenced this issue May 12, 2019

Merge pull request #2325 from mc12345678/v156-admin-products_to_categ…
…ories-update-2311

Update products_to_categories.php issue #2311
@drbyte

This comment has been minimized.

Copy link
Member

commented May 12, 2019

Closed by #2325

@drbyte drbyte closed this May 12, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.