VvebOIDC/admin/controller/product/product.php

276 lines
8.6 KiB
PHP

<?php
/**
* Vvveb
*
* Copyright (C) 2022 Ziadin Givan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Vvveb\Controller\Product;
use function Vvveb\__;
use Vvveb\Controller\Content\Edit;
use function Vvveb\dashesToCamelCase;
use Vvveb\Sql\Product_Option_ValueSQL;
use Vvveb\Sql\Product_OptionSQL;
use Vvveb\Sql\Product_VariantSQL;
use Vvveb\Sql\ProductSQL;
class Product extends Edit {
protected $type = 'product';
protected $object = 'product';
protected $module = 'product/product';
protected $list = 'product/products';
protected $revisions = true;
function saveVariants() {
$post = &$this->request->post;
$post['product_variant'] = $post['product_variant'] ?? [];
if ($post['product_variant']) {
$deleteVariant = $this->request->post['delete']['product_variant_id'] ?? [];
$variantSql = new Product_VariantSQL();
unset($post['product_variant']['#'], $post['product_variant']['0']);
foreach ($post['product_variant'] as $i => $opt) {
$opt['product_id'] = $this->product_id;
if ($opt['product_variant_id']) {
//existing variant
$variantSql->edit([
'product_variant' => $opt,
'product_variant_id' => $opt['product_variant_id'],
] + $this->global);
} else {
// new variant
unset($opt['product_variant_id']);
$result = $variantSql->add(['product_variant' => $opt] + $this->global);
if ($result && $result['product_variant']) {
//set new id to use for variant values
$opt['product_variant_id'] = $result['product_variant'];
}
}
}
if ($deleteVariant) {
$variantSql->delete(['product_variant_id' => $deleteVariant] + $this->global);
}
}
}
function saveOptions() {
$post = &$this->request->post;
$post['product_option'] = $post['product_option'] ?? [];
if ($post['product_option']) {
$deleteOption = $this->request->post['delete']['product_option_id'] ?? [];
$deleteOptionValue = $this->request->post['delete']['product_option_value_id'] ?? [];
$optionSql = new Product_OptionSQL();
$productOptionValueSql = new Product_Option_ValueSQL();
unset($post['product_option']['#'], $post['product_option']['0']);
foreach ($post['product_option'] as $i => $opt) {
$opt['product_id'] = $this->product_id;
if ($opt['product_option_id']) {
//existing option
$optionSql->edit([
'product_option' => $opt,
'product_option_id' => $opt['product_option_id'],
] + $this->global);
} else {
// new option
unset($opt['product_option_id']);
$result = $optionSql->add(['product_option' => $opt] + $this->global);
if ($result && $result['product_option']) {
//set new id to use for option values
$opt['product_option_id'] = $result['product_option'];
}
}
if (isset($opt['product_option_value'])) {
unset($opt['product_option_value']['#']);
foreach ($opt['product_option_value'] as $j => $value) {
//set parent option id
$value['product_option_id'] = $opt['product_option_id'];
$value['option_id'] = $opt['option_id'];
$value['product_id'] = $this->product_id;
if ($value['product_option_value_id']) {
//existing option value
$productOptionValueSql->edit([
'product_option_value' => $value,
'product_option_value_id' => $value['product_option_value_id'],
] + $this->global);
} else {
unset($value['product_option_value_id']);
$result = $productOptionValueSql->add(['product_option_value' => $value] + $this->global);
}
}
}
}
if ($deleteOptionValue) {
$productOptionValueSql->delete(['product_option_value_id' => $deleteOptionValue] + $this->global);
}
if ($deleteOption) {
$optionSql->delete(['product_option_id' => $deleteOption] + $this->global);
}
}
}
function save() {
$post = &$this->request->post;
$post['requires_shipping'] = isset($post['requires_shipping']) ? 1 : 0;
$post['subscription_onetime'] = isset($post['subscription_onetime']) ? 1 : 0;
$post['manufacturer_id'] = isset($post['manufacturer_id']) ? ($post['manufacturer_id'] ?: 0) : null;
$post['vendor_id'] = isset($post['vendor_id']) ? ($post['vendor_id'] ?: 0) : null;
parent::save();
$this->product_id = $this->request->get[$this->object . '_id'] ?? $post[$this->object . '_id'] ?? false;
if ($this->product_id) {
$this->saveOptions();
$this->saveVariants();
$product = new ProductSQL();
$features = ['related', /*'variant',*/ 'subscription', 'discount', 'promotion', 'points', 'attribute', 'digital_asset'];
foreach ($features as $feature) {
$feature = $this->object . '_' . $feature; //eg: product_related
$data = $this->request->post[$feature] ?? [];
if ($data) {
$fn = lcfirst(dashesToCamelCase($feature, '_')); //eg: $product->productRelated()
unset($data['#']);
$product->$fn([$this->object . '_id' => $this->product_id, $feature => array_unique($data, SORT_REGULAR)]);
}
}
}
return $this->index();
}
private function optionCombinations($arr) {
$names = [];
$values = [];
foreach ($arr as $optionId => $set) {
if (! $names) {
foreach ($set as $i => $val) {
$names[] = $val;
$values[] = $optionId . ':' . $i;
}
} else {
$length = count($names);
$newNames = [];
$newValues = [];
for ($l = 0; $l < $length; $l++) {
$currName = $names[$l];
foreach ($set as $j => $val) {
$newNames[] = $currName . ' / ' . $val;
$newValues[] = $values[$l] . ',' . $optionId . ':' . $j;
}
}
$names = $newNames;
$values = $newValues;
}
}
return [$names, $values];
}
function index() {
parent::index();
$view = $this->view;
$product = new ProductSQL();
$options = (isset($view->product['product_id']) ? $view->product : $this->global);
$data = $product->getData($options);
if (isset($data['option'])) {
foreach ($data['option'] as $id => &$option) {
unset($option['array_key']);
}
} else {
$data['option'] = [];
}
$optionIds = [];
if (isset($view->product['product_option'])) {
$product_option_value = &$view->product['product_option_value'];
$product_option = &$view->product['product_option'];
$option_value_content = [];
$names = [];
$default = '';
if ($view->product['language_id'] != $this->global['default_language_id']) {
$default = '[' . __('No translation') . ']';
}
foreach ($view->product['option_value_content'] as &$value) {
$option_value_content[$value['option_id']][$value['option_value_id']] = $value;
$names[$value['option_value_id']] = $value['name'] ?? $default;
//$optionIds[$value['product_option_id']][$value['product_option_value_id']] = $value['name'];
}
foreach ($product_option_value as &$value) {
if (isset($product_option[$value['product_option_id']])) {
$product_option[$value['product_option_id']]['values'][$value['product_option_value_id']] = $value;
$optionIds[$value['product_option_id']][$value['product_option_value_id']] = $names[$value['option_value_id']] ?? $default;
}
}
$view->product['option_value_content'] = $option_value_content;
} else {
$view->product['product_option'] = [];
}
$view->combinations = [];
if ($optionIds) {
$combinations = $this->optionCombinations($optionIds);
$view->combinations = array_combine($combinations[1], $combinations[0]);
}
$view->product['manufacturer_id'] = (($view->product['manufacturer_id'] ?? 0) ? $view->product['manufacturer_id'] : '');
$view->product['vendor_id'] = (($view->product['vendor_id'] ?? 0) ? $view->product['vendor_id'] : '');
$view->product['status'] = $view->product['status'] ?? 1;
$data['subtract_stock'] = [1 => __('Yes'), 0 => __('No')]; //Subtract stock options
$data['status'] = [0 => __('Disabled'), 1 => __('Enabled')];
$view->set($data);
}
}