/** * (non-PHPdoc) * @see StaticsPageAbstract::getData() */ public function getData($sender, $param) { $results = $errors = array(); try { $dateFrom = trim($param->CallbackParameter->dateRange->from); $dateTo = trim($param->CallbackParameter->dateRange->to); $step = trim($param->CallbackParameter->dateRange->step); $showPrice = $param->CallbackParameter->showPrice; $timeRange = $this->_getXnames($dateFrom, $dateTo, $step); $names = array_keys($timeRange); $productIds = $param->CallbackParameter->productIds; if (count($productIds) === 0) { $productIds = $this->_topProductIds(); } $series = array(); foreach ($productIds as $pid) { $data = array_fill(0, count($names), 0); $name = 'Invalid Pid=' . $pid; if (($product = Product::get($pid)) instanceof Product) { $name = $product->getSku(); $data = $this->_getSeries($timeRange, $dateFrom, $dateTo, array($product->getId()), $showPrice); } $series[] = array('name' => $name, 'data' => $data); } $results = array('chart' => array('type' => 'line'), 'title' => array('text' => 'Product Sales Trend', 'x' => -20), 'subtitle' => array('text' => 'Data is based on date range between "' . $dateFrom . '" to "' . $dateTo . '"', 'x' => -20), 'xAxis' => array('categories' => $names), 'yAxis' => array('title' => array('text' => $showPrice === true ? 'Order Amount ($)' : 'Ordered Qty')), 'series' => $series); } catch (Exception $ex) { $errors[] = $ex->getMessage(); } $param->ResponseData = StringUtilsAbstract::getJson($results, $errors); }
public function indexAction() { $categories = new Category(); //$this->view->categories = array ('1','2','3','4'); //$this->view->categories = $categories->fetchAll(); //$this->_helper->actionStack('detail-list'); //$this->_forward('detail-list'); //$this->rrr(); $front = Zend_Controller_Front::getInstance(); if ($front->getRequest()->getParam('controller') == 'toy') { $toy_id = $front->getRequest()->getParam('toy_id'); $Product = new Product(); $toy = $Product->get($toy_id); $cat_id = $toy['categoryId']; $this->view->current_id = $cat_id; $this->view->p_type = 'toy'; } else { $cat_id = $front->getRequest()->getParam('cat_id'); $cat_id = $cat_id ? $cat_id : 0; $this->view->current_id = $cat_id; $this->view->p_type = 'category'; } //print_r($cat_id);exit; $this->view->categories = $categories->get_sort_categories($cat_id); }
/** * saveOrder * * @param unknown $sender * @param unknown $param * * @throws Exception * */ public function saveOrder($sender, $param) { $results = $errors = array(); $daoStart = false; try { Dao::beginTransaction(); $daoStart = true; $supplier = Supplier::get(trim($param->CallbackParameter->supplier->id)); if (!$supplier instanceof Supplier) { throw new Exception('Invalid Supplier passed in!'); } $supplierContactName = trim($param->CallbackParameter->supplier->contactName); $supplierContactNo = trim($param->CallbackParameter->supplier->contactNo); $supplierEmail = trim($param->CallbackParameter->supplier->email); if (!empty($supplierContactName) && $supplierContactName !== $supplier->getContactName()) { $supplier->setContactName($supplierContactName); } if (!empty($supplierContactNo) && $supplierContactNo !== $supplier->getContactNo()) { $supplier->setContactNo($supplierContactNo); } if (!empty($supplierEmail) && $supplierEmail !== $supplier->getEmail()) { $supplier->setEmail($supplierEmail); } $supplier->save(); $purchaseOrder = PurchaseOrder::create($supplier, trim($param->CallbackParameter->supplierRefNum), $supplierContactName, $supplierContactNo, StringUtilsAbstract::getValueFromCurrency(trim($param->CallbackParameter->shippingCost)), StringUtilsAbstract::getValueFromCurrency(trim($param->CallbackParameter->handlingCost)))->setTotalAmount(StringUtilsAbstract::getValueFromCurrency(trim($param->CallbackParameter->totalPaymentDue)))->setEta(trim($param->CallbackParameter->eta))->setStatus(PurchaseOrder::STATUS_NEW)->save()->addComment(trim($param->CallbackParameter->comments), Comments::TYPE_PURCHASING); foreach ($param->CallbackParameter->items as $item) { if (!($product = Product::get(trim($item->productId))) instanceof Product) { throw new Exception('Invalid Product passed in!'); } $purchaseOrder->addItem($product, StringUtilsAbstract::getValueFromCurrency(trim($item->unitPrice)), 0 - abs(intval(trim($item->qtyOrdered)))); } if ($param->CallbackParameter->submitToSupplier === true) { $purchaseOrder->setStatus(PurchaseOrder::STATUS_ORDERED); } // For credit PO if (isset($param->CallbackParameter->type) && trim($param->CallbackParameter->type) === 'CREDIT') { $purchaseOrder->setIsCredit(true); if (isset($param->CallbackParameter->po) && ($fromPO = PurchaseOrder::get(trim($param->CallbackParameter->po->id))) instanceof PurchaseOrder) { $purchaseOrder->setFromPO($fromPO); } } $purchaseOrder->save(); $daoStart = false; Dao::commitTransaction(); $results['item'] = $purchaseOrder->getJson(); if (isset($param->CallbackParameter->confirmEmail) && trim($confirmEmail = trim($param->CallbackParameter->confirmEmail)) !== '') { $pdfFile = EntityToPDF::getPDF($purchaseOrder); $asset = Asset::registerAsset($purchaseOrder->getPurchaseOrderNo() . '.pdf', file_get_contents($pdfFile), Asset::TYPE_TMP); EmailSender::addEmail('*****@*****.**', $confirmEmail, 'BudgetPC Purchase Order:' . $purchaseOrder->getPurchaseOrderNo(), 'Please Find the attached PurchaseOrder(' . $purchaseOrder->getPurchaseOrderNo() . ') from BudgetPC.', array($asset)); EmailSender::addEmail('*****@*****.**', '*****@*****.**', 'BudgetPC Purchase Order:' . $purchaseOrder->getPurchaseOrderNo(), 'Please Find the attached PurchaseOrder(' . $purchaseOrder->getPurchaseOrderNo() . ') from BudgetPC.', array($asset)); $purchaseOrder->addComment('An email sent to "' . $confirmEmail . '" with the attachment: ' . $asset->getAssetId(), Comments::TYPE_SYSTEM); } } catch (Exception $ex) { if ($daoStart === true) { Dao::rollbackTransaction(); } $errors[] = $ex->getMessage(); } $param->ResponseData = StringUtilsAbstract::getJson($results, $errors); }
public function update_products() { $products = new Product(); foreach ($products->get() as $product) { $this->update_product($product); } }
public function getDefaultSearchContext() { $context = parent::getDefaultSearchContext(); $fields = $context->getFields(); $fields->push(CheckboxField::create("HasBeenUsed")); //add date range filtering $fields->push(ToggleCompositeField::create("StartDate", "Start Date", array(DateField::create("q[StartDateFrom]", "From")->setConfig('showcalendar', true), DateField::create("q[StartDateTo]", "To")->setConfig('showcalendar', true)))); $fields->push(ToggleCompositeField::create("EndDate", "End Date", array(DateField::create("q[EndDateFrom]", "From")->setConfig('showcalendar', true), DateField::create("q[EndDateTo]", "To")->setConfig('showcalendar', true)))); //must be enabled in config, because some sites may have many products = slow load time, or memory maxes out //future solution is using an ajaxified field if (self::config()->filter_by_product) { $fields->push(ListboxField::create("Products", "Products", Product::get()->map()->toArray())->setMultiple(true)); } if (self::config()->filter_by_category) { $fields->push(ListboxField::create("Categories", "Categories", ProductCategory::get()->map()->toArray())->setMultiple(true)); } if ($field = $fields->fieldByName("Code")) { $field->setDescription("This can be a partial match."); } //get the array, to maniplulate name, and fullname seperately $filters = $context->getFilters(); $filters['StartDateFrom'] = GreaterThanOrEqualFilter::create('StartDate'); $filters['StartDateTo'] = LessThanOrEqualFilter::create('StartDate'); $filters['EndDateFrom'] = GreaterThanOrEqualFilter::create('EndDate'); $filters['EndDateTo'] = LessThanOrEqualFilter::create('EndDate'); $context->setFilters($filters); return $context; }
/** * @covers QueueController::Add * @todo Implement testAdd(). */ public function testAdd() { $person = Person::factory('adult'); $person->name = 'Poehavshiy'; $person->add(); $store = Store::factory('Grocery'); $store->name = 'Prison'; $store->add(); $product = new Product(); $product->name = 'Sladkiy hleb'; $product->add(); $request = Application::getInstance()->request; $request->setParams(array('storeId' => $store->id, 'personId' => $person->id, 'product_' . $product->id => 'on')); $personId = $request->p('personId'); $storeId = $request->p('storeId'); $store = Store::get($storeId); $person = Person::get($personId); $store->queue->add($person); $person->basket->drop(); $name = 'product_' . $product->id; $value = $product; if (preg_match_all('/^product_(\\d+)$/', $name, $matches)) { $person->basket->add(Product::get($matches[1][0])); } }
public function doAddItemToCart($data) { $product = Product::get()->byID($data['ProductID']); $customisations = array(); foreach ($data as $key => $value) { if (!(strpos($key, 'customise') === false) && $value) { $custom_data = explode("_", $key); if ($custom_item = ProductCustomisation::get()->byID($custom_data[1])) { $modify_price = 0; // Check if the current selected option has a price modification if ($custom_item->Options()->exists()) { $option = $custom_item->Options()->filter("Title", $value)->first(); $modify_price = $option ? $option->ModifyPrice : 0; } $customisations[] = array("Title" => $custom_item->Title, "Value" => $value, "ModifyPrice" => $modify_price); } } } if ($product) { $cart = ShoppingCart::create(); $cart->add($product, $data['Quantity'], $customisations); $cart->save(); // Clear any postage data that has been set Session::clear("Commerce.PostageID"); $message = _t('Commerce.AddedItemToCart', 'Added item to your shopping cart'); $message .= ' <a href="' . $cart->Link() . '">'; $message .= _t('Commerce.ViewCart', 'View cart'); $message .= '</a>'; $this->controller->setSessionMessage("success", $message); } return $this->controller->redirectBack(); }
public function setProduct(Product $product) { if ($product) { $this->api()->addProduct($product->get()); } return $this; }
public function dataAction() { $w = 80; $h = 100; $img = $this->_getParam('img'); $ar_img = split('\\.', $img); //print_r($ar_img);exit; $Product = new Product(); $product = $Product->get($ar_img[0]); if ($product && $product['picture']) { $res = GetWebPage($product['picture'], $RetStatus); //header('Content-type: image/jpg'); //print_r($res);exit; //$ar = getimagesizefromstring($res); $im = imagecreatefromstring($res); $width = imagesx($im); $height = imagesy($im); //print_r($width." ".$height); if ($width > $height) { $new_height = $w * $height / $width; $new_width = $w; } else { $new_height = $h; $new_width = $h * $width / $height; } $im_new = imagecreatetruecolor($new_width, $new_height); //imagecopyresized($im_new,$im,0, 0, 0, 0, $new_width, $new_height, $width, $height); imagecopyresampled($im_new, $im, 0, 0, 0, 0, $new_width, $new_height, $width, $height); header('Content-type: image/jpg'); imagejpeg($im_new); } $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout->disableLayout(); }
public function processRecord($record, $columnMap, &$results, $preview = false) { // Get Current Object $objID = parent::processRecord($record, $columnMap, $results, $preview); $object = DataObject::get_by_id($this->objectClass, $objID); $this->extend("onBeforeProcess", $object, $record, $columnMap, $results, $preview); // Loop through all fields and setup associations foreach ($record as $key => $value) { // Find any categories (denoted by a 'CategoryXX' column) if (strpos($key, 'Category') !== false) { $category = CatalogueCategory::get()->filter("Title", $value)->first(); if ($category) { $object->Categories()->add($category); } } // Find any Images (denoted by a 'ImageXX' column) if (strpos($key, 'Image') !== false && $key != "Images") { $image = Image::get()->filter("Name", $value)->first(); if ($image) { $object->Images()->add($image); } } // Find any related products (denoted by a 'RelatedXX' column) if (strpos($key, 'Related') !== false && $key != "RelatedProducts") { $product = Product::get()->filter("StockID", $value)->first(); if ($product) { $object->RelatedProducts()->add($product); } } } $this->extend("onAfterProcess", $object, $record, $columnMap, $results, $preview); $object->destroy(); unset($object); return $objID; }
public function handler() { $params = $this->getURLParams(); $catalog = null; $product = null; // Only deal with AJAX requests if (!$this->request->isAjax()) { return $this->httpError(401, 'Bad request'); } switch ($params['Action']) { case 'Catalog': $catalog = Catalog::get()->byId($params['ID']); break; case 'Product': $product = Product::get()->byID($params['ID']); break; default: return $this->httpError(401, 'Bad request'); } // Make sure we have some data. if (!$catalog && !$product) { return $this->httpError(404, 'Sorry, we couldn\'t find anything.'); } // If there's a catalog, fetch its JSON, otherwise fetch the product's JSON. $JSON = $catalog ? $catalog->getCatalogJSON() : $product->getProductJSON(); $response = $this->getResponse()->addHeader('Content-type', 'application/json; charset=utf-8'); $response->setBody($JSON); return $response; }
protected function query($phrase) { $phrase = Convert::raw2sql($phrase); //prevent sql injection $query = Product::get()->filter("ShowInSearch", true)->dataQuery(); if (!empty($phrase) && ($fields = $this->matchFields())) { $scoresum = array(); $phrasewords = explode(" ", $phrase); $maxstrength = count($fields); $SQL_matchphrase = "" . implode("* ", $phrasewords) . "*"; foreach ($fields as $weight => $field) { //TODO: get this working $strength = count($fields) - $weight; $query->select[] = "(MATCH({$field}) AGAINST ('{$phrase}' IN BOOLEAN MODE)) * {$maxstrength} AS \"Relevance{$weight}_exact\""; $query->select[] = "(MATCH({$field}) AGAINST ('{$SQL_matchphrase}' IN BOOLEAN MODE)) * {$strength} AS \"Relevance{$weight}\""; $scoresum[] = "\"Relevance{$weight}\" + \"Relevance{$weight}_exact\""; //exact match gets priority } $likes = array(); foreach ($fields as $field) { foreach ($phrasewords as $word) { $likes[] = $field . " LIKE '%{$word}%'"; } } $query->where("(" . implode(" OR ", $likes) . ")"); } return $query; }
public function updateSetting($sender, $param) { $result = $errors = array(); try { $result = $products = array(); $systemSetting = SystemSettings::getByType(SystemSettings::TYPE_SYSTEM_BUILD_PRODUCTS_ID); foreach ($param->CallbackParameter as $type => $ids) { $result[$type] = array(); $products[$type] = array(); foreach ($ids as $index => $id) { $id = intval(trim($id)); if (($product = Product::get($id)) instanceof Product) { $result[$type][] = $id; $products[$type][] = $product->getJson(); } } } Dao::beginTransaction(); $systemSetting->setValue(json_encode($result))->save(); Dao::commitTransaction(); } catch (Exception $ex) { // Dao::rollbackTransaction(); $errors[] = $ex->getMessage(); } $param->ResponseData = StringUtilsAbstract::getJson($products, $errors); }
public function handleRequest(SS_HTTPRequest $request, DataModel $model) { $this->pushCurrent(); $this->urlParams = $request->allParams(); $this->request = $request; $this->response = new SS_HTTPResponse(); $this->setDataModel($model); $urlsegment = $request->param('URLSegment'); $this->extend('onBeforeInit'); $this->init(); $this->extend('onAfterInit'); // First check products against URL segment if ($product = Product::get()->filter(array('URLSegment' => $urlsegment, 'Disabled' => 0))->first()) { $controller = Catalogue_Controller::create($product); } elseif ($category = ProductCategory::get()->filter('URLSegment', $urlsegment)->first()) { $controller = Catalogue_Controller::create($category); } else { // If CMS is installed if (class_exists('ModelAsController')) { $controller = ModelAsController::create(); } } $result = $controller->handleRequest($request, $model); $this->popCurrent(); return $result; }
/** * Display a listing of the resource. * * @return Response */ public function index() { $products = Product::join('categories', 'categories.id', '=', 'products.category_id')->where('categories.deleted_at', '=', null)->select('products.public_id', 'products.product_key', 'products.notes', 'products.is_product', 'products.cost', 'categories.name as category_name', 'categories.id as category_id')->get(); $products = Product::get(); // print_r($products); // return 0; return View::make('productos.index', array('products' => $products)); }
/** * Returns a list of Products. * extend with alterProducts to use a different set other than Product::get() * @return DataList or ArrayList of Products */ function ProductList() { $products = $this->extend('alterProducts'); if (count($products)) { $products = array_pop($products); } return $products ? $products : Product::get(); }
public function show(SS_HTTPRequest $request) { $product = Product::get()->byID($request->param('ID')); if (!$product) { return $this->httpError(404, 'That product could not be found'); } return array('Product' => $product); }
/** * Get a full list of products, filtered by a category if provided. * * @param ParentCategory the ID of */ public function getCommerceProducts($ParentCategory = null) { $products = Product::get(); if (isset($ParentCategory) && is_int($ParentCategory)) { $products = $products->where("ParentID = {$ParentID}"); } return $products; }
/** * Find any items in the product catalogue with a matching SKU, good for * adding "Order again" links in account panels or finding "Most ordered" * etc. * * @return Product */ public function Product() { // If the SKU is set, and it matches a product, return product if ($this->SKU && ($product = Product::get()->filter("SKU", $this->SKU)->first())) { return $product; } // If nothing has matched, return an empty product return Product::create(); }
public function provideGridSheetData($modelClass) { if (self::ModelClass == $modelClass) { $mode = static::own_config('products_reading_mode'); Versioned::set_reading_mode($mode); $products = Product::get(); return $products; } }
public function updateCMSFields(FieldList $fields) { /** @var FormField $idField */ $fields->removeByName('ShippableID'); // TODO make this more friendly for multiple extended classes $shippables = Product::get()->map()->toArray(); $fields->insertBefore(new Select2Field('ShippableID', 'Shippable', $shippables, $this->owner->ShippableID), 'Price'); $regions = Region_Shipping::get()->map()->toArray(); $fields->insertBefore(new Select2Field('RegionID', 'Region', $regions, $this->owner->RegionID), 'Price'); }
public function provideEditableColumns(array &$fieldSpecs) { xdebug_break(); if (self::ModelClass == $this->owner->class) { $fieldSpecs += array('ProductID' => array('title' => 'Product Name', 'callback' => function ($record) { return new Select2Field('ProductID', '', Product::get()->map()->toArray()); }), 'StockLevel' => array('title' => 'In Stock', 'callback' => function ($record, $col) { return new NumericField('StockLevel'); })); } }
/** * getCMSFields * Construct the FieldList used in the CMS. To provide a * smarter UI we don't use the scaffolding provided by * parent::getCMSFields. * * @return FieldList */ public function getCMSFields() { Requirements::css('torindul-silverstripe-shop/css/LeftAndMain.css'); //Product Item not yet created $select_product_item = Tab::create("Item", HeaderField::create("Add Order Item"), CompositeField::create(DropdownField::create("OriginalProductID", "Select Product", Product::get()->sort("Title ASC")->map())->setEmptyString("(Select a product)"))); //Product Item has been created $edit_product_item = Tab::create("Item", HeaderField::create("Order Item"), CompositeField::create(ReadonlyField::create("Title", "Product")->setRightTitle("You will need to remove this item and add another should you wish to change the product."), ReadonlyField::create("SKU", "SKU"), FieldGroup::create(NumericField::create("Price", "Cost per item"), DropdownField::create("Discounted", "Is this the sale price?", array("0" => "No", "1" => "Yes")), NumericField::create("Quantity", "Quantity ordered"))->setTitle("Pricing (" . Product::getDefaultCurrency() . ") "), ReadonlyField::create("SubTotal", "Subtotal (" . Product::getDefaultCurrency() . ")", StoreCurrency::convertToCurrency($this->Price * $this->Quantity)), ReadonlyField::create("TAX", $this->TaxClassName . " (" . Product::getDefaultCurrency() . ")", $this->calculateItemTax())->setRightTitle($this->TaxCalculation == 1 ? "Subtotal is inclusive of this tax." : "Subtotal is exclusive of this tax."), ReadonlyField::create("Total", "Total (" . Product::getDefaultCurrency() . ")", $this->TaxCalculation == 1 ? StoreCurrency::convertToCurrency($this->Price * $this->Quantity) : StoreCurrency::convertToCurrency($this->Price * $this->Quantity + $this->calculateItemTax())))); //Create the FieldList and push the either of the above Tabs to the Root TabSet based on if Product Item exists yet or not. $fields = FieldList::create($root = TabSet::create('Root', $this->exists() ? $edit_product_item : $select_product_item)); return $fields; }
public function index() { switch ($this->type) { case 'categories': $list = Category::get(array('id', 'name', 'slug')); break; default: $list = Product::get(array('id', 'name', 'slug', 'pricing', 'in_stock', 'published')); break; } $this->layout->content = View::make('admin.control_panel.list', array('type' => $this->type, 'list' => $list)); }
public function updateCMSFields(FieldList $fields) { $fields->addFieldToTab("Root.Settings", DropdownField::create("ProductGroupID", _t("GroupedProduct.AddToGroup", "Add this product to a group"), Product::get()->filter("ClassName", "GroupedProduct")->map())->setEmptyString(_t("GroupedProduct.SelectProduct", "Select a Product"))); // If this is a child product, remove some fields we don't need if ($this->owner->ProductGroupID) { $fields->removeByName("Content"); $fields->removeByName("Metadata"); $fields->removeByName("Related"); $fields->removeByName("Categories"); $fields->removeByName("TaxRate"); } }
/** * Find the current category via its URL * * @return Product * */ public static function get_current_product() { $segment = Controller::curr()->request->param('URLSegment'); $return = null; if ($segment) { $return = Product::get()->filter(array('URLSegment' => $segment, "Disabled" => 0))->first(); } if (!$return) { $return = Product::create(); } return $return; }
/** * (non-PHPdoc) * @see CRUDPageAbstract::_getEndJs() */ protected function _getEndJs() { $from = isset($this->Request['from']) ? $this->Request['from'] : ''; $to = isset($this->Request['to']) ? $this->Request['to'] : ''; $productId = isset($this->Request['productid']) ? $this->Request['productid'] : ''; $js = parent::_getEndJs(); $js .= "pageJs"; $js .= "._bindSearchKey()"; $js .= "._loadDataPicker()"; $js .= ".setPreData(" . json_encode($from) . ", " . json_encode($to) . ", " . json_encode(($product = Product::get($productId)) instanceof Product ? $product->getJson() : '') . ")"; $js .= ";"; return $js; }
/** * Retrieve a set of products, based on the given parameters. Checks get query for sorting and pagination. * * @param string $extraFilter Additional SQL filters to apply to the Product retrieval * @param bool $recursive include sub-categories * @return PaginatedList */ public function ProductsShowable($recursive = true) { // Figure out the categories to check $groupids = array($this->ID); if (!empty($recursive) && self::config()->include_child_groups) { $groupids += $this->AllChildCategoryIDs(); } $products = Product::get()->leftJoin('Product_ProductCategories', '"Product_ProductCategories"."ProductID" = "Product"."ID"')->filterAny(array('ParentID' => $groupids, 'Product_ProductCategories.ProductCategoryID' => $groupids)); if (self::config()->must_have_price) { $products = $products->filter("BasePrice:GreaterThanOrEqual", 0); } return $products; }
function run($request) { $myProductGroup = ProductGroup::get()->first(); $myProduct = Product::get()->first(); $html = "\r\n\t\tPlease use the links below:\r\n\t\t<ul>\r\n\t\t\t<li><a href=\"/shoppingcart/debug/\" target=\"_debug\">debug cart</a></li>\r\n\t\t\t<li><a href=\"/shoppingcart/ajaxtest/?ajax=1\" target=\"_debug\">view cart response</a></li>"; if ($myProductGroup) { $html .= "\r\n\t\t\t<li><a href=\"" . $myProductGroup->Link("debug") . "\" target=\"_debug\">debug product group</a></li>"; } if ($myProduct) { $html .= "\r\n\t\t\t<li><a href=\"" . $myProduct->Link("debug") . "\" target=\"_debug\">debug product</a></li>"; } $html .= "\r\n\t\t</ul>"; DB::alteration_message("{$html}"); }
public function testProductCategoryProducts() { $category = $this->objFromFixture('ProductCategory', 'general'); $productA = $this->objFromFixture('Product', 'productA'); $productB = $this->objFromFixture('Product', 'productB'); $this->loginAs('admin'); $category->doPublish(); $productA->doPublish(); $productB->doPublish(); $this->logOut(); $this->assertEquals(2, $category->Products()->count()); $list = Product::get()->innerJoin('ProductCategory_Products', "\"ProductCategory_Products\".\"ProductID\" = \"Product\".\"ID\"")->where("\"ProductCategory_Products\".\"ProductCategoryID\" = '" . $category->ID . "' OR \"ParentID\" = '" . $category->ID . "'"); $this->assertEquals(2, $list->count()); }