public function index() { if ($tags = \Shop\Models\Products::getTags()) { sort($tags); } else { $tags = array(); } $model = (new \Shop\Models\Tags())->populateState(); $state = $model->getState(); $needle = $model->getState('filter.keyword'); if (!empty($needle)) { $tags = array_filter($tags, function ($tags) use($needle) { return stripos($tags, $needle) !== false; }); } if (!empty($tags)) { $tags = array_map(function ($el) { return new \Shop\Models\Tags(array('title' => $el)); }, $tags); } \Base::instance()->set('state', $state); \Base::instance()->set('tags', $tags); $this->app->set('meta.title', 'Tags | Shop'); $view = \Dsc\System::instance()->get('theme'); echo $view->render('Shop/Admin/Views::tags/index.php'); }
public function forSelection() { $field = $this->input->get('value', '_id', 'default'); $term = $this->input->get('q', null, 'default'); $key = new \MongoRegex('/' . $term . '/i'); $results = \Shop\Models\Products::forSelection(array('title' => $key), $value); $response = new \stdClass(); $response->more = false; $response->term = $term; $response->results = $results; return $this->outputJson($response); }
data: function (term, page) { return { q: term }; }, results: function (data, page) { return {results: data.results}; } } <?php if ($flash->old('discount_target_products')) { ?> , initSelection : function (element, callback) { var data = <?php echo json_encode(\Shop\Models\Products::forSelection(array('_id' => array('$in' => array_map(function ($input) { return new \MongoId($input); }, $flash->old('discount_target_products')))))); ?> ; callback(data); } <?php } ?> }); jQuery("#target_shipping_methods").select2({ allowClear: true, placeholder: "Search...", multiple: true,
data: function (term, page) { return { q: term }; }, results: function (data, page) { return {results: data.results}; } } <?php if ($flash->old('excluded_products')) { ?> , initSelection : function (element, callback) { var data = <?php echo json_encode(\Shop\Models\Products::forSelection(array('_id' => array('$in' => array_map(function ($input) { return new \MongoId($input); }, (array) $flash->old('excluded_products')))))); ?> ; callback(data); } <?php } ?> }); jQuery("#excluded_collections").select2({ allowClear: true, placeholder: "Search...", multiple: true, minimumInputLength: 3,
<div class="row"> <div class="col-md-2"> <h3>Tags</h3> <p class="help-block">Any products tagged with these tags will be included in the collection.</p> </div> <!-- /.col-md-2 --> <div class="col-md-10"> <div class="form-group"> <input name="tags" data-tags='<?php echo json_encode(\Shop\Models\Products::getTags()); ?> ' value="<?php echo implode(",", (array) $flash->old('tags')); ?> " type="text" class="form-control ui-select2-tags" /> </div> <!-- /.form-group --> </div> <!-- /.col-md-10 --> </div> <!-- /.row -->
protected function afterSave() { parent::afterSave(); if (!empty($this->__update_products_ordering)) { // $to_update = find all products in this collection that dont have an ordering value for this collection // if there are some, // get a count of all products in this collection, set $start = count to push them to the end // loop though $to_update and set their ordering value = $start + $key $conditions = \Shop\Models\Collections::getProductQueryConditions($this->id); $conditions['collections.' . $this->id . '.ordering'] = null; $to_update = \Shop\Models\Products::collection()->distinct('_id', $conditions); if (!empty($to_update)) { $collection_id = (string) $this->id; unset($conditions['collections.' . $this->id . '.ordering']); $count = \Shop\Models\Products::collection()->count($conditions); foreach ($to_update as $key => $product_id) { $ordering = $count + $key; $product = (new \Shop\Models\Products())->setState('filter.id', (string) $product_id)->getItem(); if (!empty($product->id)) { $product->update(array('collections.' . $collection_id . '.ordering' => (int) $ordering), array('overwrite' => false)); } } } } }
ajax: { url: "./admin/shop/products/forSelection", dataType: 'json', data: function (term, page) { return { q: term }; }, results: function (data, page) { return {results: data.results}; } } <?php if (count($products)) { ?> , initSelection : function (element, callback) { var data = <?php echo json_encode(\Shop\Models\Products::forSelection(array('_id' => array('$in' => array_map(function ($input) { return new \MongoId($input); }, $products))))); ?> ; callback(data); } <?php } ?> }); }); </script>
/** * \T (tab) delimited feed of products * * http://www.pepperjamnetwork.com/doc/product_feed_advanced.html * */ public function productsTxt() { $settings = \Shop\Models\Settings::fetch(); if (!$settings->{'feeds.pepperjam_products.enabled'}) { return; } $this->app->set('CACHE', true); $cache = \Cache::instance(); $cache_period = 3600 * 24; if ($cache->exists('pepperjam.products_text', $string)) { header('Content-Type: text/plain; charset=utf-8'); echo $string; exit; } $base = \Dsc\Url::base(); $model = (new \Shop\Models\Products())->setState('filter.published_today', true)->setState('filter.inventory_status', 'in_stock')->setState('filter.publication_status', 'published'); $conditions = $model->conditions(); $conditions['product_type'] = array('$nin' => array('giftcard', 'giftcards')); $cursor = \Shop\Models\Products::collection()->find($conditions)->sort(array('title' => 1)); //->limit(10); /** * name sku buy_url image_url description_short description_long price manufacturer */ $column_headers = array('name', 'sku', 'buy_url', 'image_url', 'description_short', 'description_long', 'price', 'manufacturer'); $string = implode("\t", $column_headers) . "\r\n"; foreach ($cursor as $product_doc) { $product = new \Shop\Models\Products($product_doc); foreach ($product->variantsInStock() as $variant) { $valid = true; $price = $product->price($variant['id']); // Skip products where price == 0.00 if (empty($price)) { continue; } $pieces = array('name' => null, 'sku' => null, 'buy_url' => null, 'image_url' => null, 'description_short' => null, 'description_long' => null, 'price' => null, 'manufacturer' => null); $pieces['name'] = $product->title; $sku = $variant['sku'] ? $variant['sku'] : $product->{'tracking.sku'}; if (!$sku) { $sku = $variant['id']; } $pieces['sku'] = $sku; $pieces['buy_url'] = $base . 'shop/product/' . $product->slug . '?variant_id=' . $variant['id']; // image_link if ($image = $variant['image'] ? $variant['image'] : $product->{'featured_image.slug'}) { $pieces['image_url'] = $base . 'asset/' . $image; } $pieces['description_short'] = $product->title . ' '; if ($attribute_title = \Dsc\ArrayHelper::get($variant, 'attribute_title')) { $pieces['description_short'] .= $attribute_title; } $pieces['description_short'] = trim($pieces['description_short']); $pieces['description_long'] = strip_tags($product->getAbstract()); $pieces['price'] = $price; if ($brand = $settings->{'feeds.pepperjam_products.brand'}) { $pieces['manufacturer'] = $brand; } global $product; //walk peices logging empty values and omiting them array_walk($pieces, function (&$value, $key) { global $product; if (empty($value)) { \Dsc\Mongo\Collections\Logs::add($product->title . ' | ID: ' . $product->id . ' is missing ' . $key, 'WARNING', 'PepperJam'); $valid = false; } }); if ($valid) { $string .= implode("\t", $pieces) . "\r\n"; } } } $cache->set('pepperjam.products_text', $string, $cache_period); header('Content-Type: text/plain; charset=utf-8'); echo $string; exit; }
/** * Add related products to the Pages model whenever it is saved * * @param unknown $event * @return \MongoId */ public function afterSaveBlogModelsPosts($event) { $model = $event->getArgument('model'); if ($model->{'shop.products'}) { \Shop\Models\Products::collection()->update(array('_id' => array('$nin' => $model->{'shop.products'}), 'blog.related' => new \MongoId((string) $model->id)), array('$pull' => array('blog.related' => new \MongoId((string) $model->id))), array('multiple' => true)); \Shop\Models\Products::collection()->update(array('_id' => array('$in' => $model->{'shop.products'})), array('$addToSet' => array('blog.related' => new \MongoId((string) $model->id))), array('multiple' => true)); } $event->setArgument('model', $model); }
/** * * @param unknown $variant_id * @param \Shop\Models\Products $product * @param array $post * @return \Shop\Models\Prefabs\CartItem */ public static function createItem($variant_id, \Shop\Models\Products $product, array $post = array()) { $options = !empty($post['options']) ? $post['options'] : array(); $quantity = !empty($post['quantity']) && $post['quantity'] > 0 ? (int) $post['quantity'] : 1; $price = $product->price($variant_id); if (!($variant = $product->variant($variant_id))) { $variant = array(); } $attribute_title = \Dsc\ArrayHelper::get($variant, 'attribute_title'); $attribute_titles = \Dsc\ArrayHelper::get($variant, 'attribute_titles'); $attributes = \Dsc\ArrayHelper::get($variant, 'attributes'); $sku = \Dsc\ArrayHelper::get($variant, 'sku'); $model_number = \Dsc\ArrayHelper::get($variant, 'model_number'); $upc = \Dsc\ArrayHelper::get($variant, 'upc'); $weight = \Dsc\ArrayHelper::get($variant, 'weight'); $image = \Dsc\ArrayHelper::get($variant, 'image'); $cartitem = new \Shop\Models\Prefabs\CartItem(array('variant_id' => (string) $variant_id, 'options' => (array) $options, 'product' => $product->cast(), 'product_id' => $product->id, 'quantity' => $quantity, 'price' => $price, 'attribute_title' => !empty($attribute_title) ? $attribute_title : null, 'attribute_titles' => !empty($attribute_titles) ? $attribute_titles : array(), 'attributes' => !empty($attributes) ? $attributes : array(), 'sku' => !empty($sku) ? $sku : $product->{'tracking.sku'}, 'model_number' => !empty($model_number) ? $model_number : $product->{'tracking.model_number'}, 'upc' => !empty($upc) ? $upc : $product->{'tracking.upc'}, 'weight' => !empty($weight) ? $weight : $product->{'shipping.weight'}, 'image' => !empty($image) ? $image : $product->{'featured_image.slug'})); return $cartitem; }
/** * Helper method for creating select list options * * @param array $query * @return multitype:multitype:string NULL */ public static function productsForSelection($tag) { return \Shop\Models\Products::forSelection(array('tags' => $tag)); }
protected function fetchConditions() { parent::fetchConditions(); $this->setCondition('product_type', 'giftcards'); }
public function productsXml() { $settings = \Shop\Models\Settings::fetch(); if (!$settings->{'feeds.gm_products.enabled'}) { return; } $this->app->set('CACHE', true); $cache = \Cache::instance(); $cache_period = 3600 * 24; if ($cache->exists('googlemerchant.products_xml', $string)) { header('Content-Type: application/xml; charset=utf-8'); echo $string; exit; } $base = \Dsc\Url::base(); $model = (new \Shop\Models\Products())->setState('filter.published_today', true)->setState('filter.inventory_status', 'in_stock')->setState('filter.publication_status', 'published'); $conditions = $model->conditions(); $conditions['product_type'] = array('$nin' => array('giftcard', 'giftcards')); $cursor = \Shop\Models\Products::collection()->find($conditions)->sort(array('title' => 1)); //->limit(10); /** * Generate XML */ $x = new \XMLWriter(); $x->openMemory(); $x->setIndent(true); $x->setIndentString(" "); $x->startDocument('1.0', 'UTF-8'); $x->startElement('rss'); $x->writeAttribute('version', '2.0'); $x->writeAttribute('xmlns:g', 'http://base.google.com/ns/1.0'); $x->startElement('channel'); $title = $settings->{'feeds.gm_products.title'} ? $settings->{'feeds.gm_products.title'} : 'Product Feed'; $x->startElement('title'); $x->text($title); $x->endElement(); // title $link = $base; $x->startElement('link'); $x->text($link); $x->endElement(); // link if ($description = $settings->{'feeds.gm_products.description'}) { $x->startElement('description'); $x->text($description); $x->endElement(); // description } foreach ($cursor as $product_doc) { $product = new \Shop\Models\Products($product_doc); foreach ($product->variantsInStock() as $variant) { $price = $product->price($variant['id']); // Skip products where price == 0.00 if (empty($price)) { continue; } $x->startElement('item'); $x->startElement('title'); $x->text($product->title); $x->endElement(); // title $x->startElement('description'); $x->text(strip_tags($product->getAbstract())); $x->endElement(); // description $x->startElement('g:link'); $x->text($base . 'shop/product/' . $product->slug); $x->endElement(); // g:link // image_link if ($image = $variant['image'] ? $variant['image'] : $product->{'featured_image.slug'}) { $x->startElement('g:image_link'); $x->text($base . 'asset/' . $image); $x->endElement(); // g:image_link } // google_product_category if ($product->{'gm_product_category'}) { $x->startElement('g:google_product_category'); $x->text($product->{'gm_product_category'}); $x->endElement(); // g:google_product_category } // TODO product_type // gender = female (or male, unisex) $gender = $settings->{'feeds.gm_products.gender'}; if ($product->{'gm_products.gender'}) { $gender = $product->{'gm_products.gender'}; } if ($gender) { $x->startElement('g:gender'); $x->text($gender); $x->endElement(); // g:gender } // age_group = adult (or newborn, infanct, toddler, kids) $age_group = $settings->{'feeds.gm_products.age_group'}; if ($product->{'gm_products.age_group'}) { $age_group = $product->{'gm_products.age_group'}; } if ($age_group) { $x->startElement('g:age_group'); $x->text($age_group); $x->endElement(); // g:age_group } // following handles color, size, pattern, material (if they are set as attributes) foreach ($product->attributes as $attribute) { $att_title = strtolower($attribute['title']); if (in_array($att_title, array('color', 'material', 'pattern', 'size'))) { $att_id = $attribute['id']; // get the attribute options $options = array(); foreach ($attribute['options'] as $option) { $options[] = $option['id']; } if ($found = array_intersect($options, $variant['attributes'])) { $key = array_search($found, $variant['attributes']); if (!empty($variant['attribute_titles'][$key])) { $x->startElement('g:' . $att_title); $x->text($variant['attribute_titles'][$key]); $x->endElement(); // g:$att_title } } } } // since we do variants: item_group_id $x->startElement('g:item_group_id'); $x->text($product->{'tracking.sku'}); $x->endElement(); // g:item_group_id $sku = $variant['sku'] ? $variant['sku'] : $product->{'tracking.sku'}; if (!$sku) { $sku = $variant['id']; } $x->startElement('g:id'); $x->text($sku); $x->endElement(); // g:id if ($brand = $settings->{'feeds.gm_products.brand'}) { $x->startElement('g:brand'); $x->text($brand); $x->endElement(); // g:brand } $x->startElement('g:mpn'); $x->text($sku); $x->endElement(); // g:mpn $x->startElement('g:price'); $x->text($price . ' USD'); $x->endElement(); // g:price $x->startElement('g:condition'); $x->text('new'); $x->endElement(); // g:condition $x->startElement('g:availability'); $x->text('in stock'); $x->endElement(); // g:availability $x->endElement(); // item } } $x->endElement(); // channel $x->endElement(); // rss $x->endDocument(); $string = $x->outputMemory(); $cache->set('googlemerchant.products_xml', $string, $cache_period); header('Content-Type: application/xml; charset=utf-8'); echo $string; }
data: function (term, page) { return { q: term }; }, results: function (data, page) { return {results: data.results}; } } <?php if ($state->get('filter.product_ids')) { ?> , initSelection : function (element, callback) { var data = <?php echo json_encode(\Shop\Models\Products::forSelection(array('_id' => array('$in' => array_map(function ($input) { return new \MongoId($input); }, explode(",", $state->get('filter.product_ids'))))))); ?> ; callback(data); } <?php } ?> }); }); </script> </li> </ul> </div> <div class="col-xs-12 col-sm-7 col-md-7 col-lg-4">
ajax: { url: "./admin/shop/products/forSelection", dataType: 'json', data: function (term, page) { return { q: term }; }, results: function (data, page) { return {results: data.results}; } } <?php if ($flash->old('title')) { ?> , initSelection : function (element, callback) { var data = <?php echo json_encode(\Shop\Models\Products::forSelection(array('_id' => array('$in' => array_map(function ($input) { return new \MongoId($input); }, (array) \Shop\Models\Tags::productIds($flash->old('title'))))))); ?> ; callback(data); } <?php } ?> }); }); </script>
<div class="portlet"> <div class="portlet-header"> <h3>Stickers</h3> <p class="help-block">Stickers display on product listing pages (collections/category landing pages) and can be used to indicate an item is "on sale", "editor's pick", or "limited availability", etc.</p> </div> <!-- /.portlet-header --> <div class="portlet-content"> <div class="input-group"> <input name="display[stickers]" data-maximum="1" data-tags='<?php echo json_encode((array) \Shop\Models\Products::distinctStickers()); ?> ' value="<?php echo implode(",", (array) $flash->old('display.stickers')); ?> " type="text" class="form-control ui-select2-tags" /> </div> <!-- /.form-group --> </div> <!-- /.portlet-content --> </div> <!-- /.portlet --> </div>