Laravel query doesn't work - php

I am trying to add wheres to my query depending on what's coming in from GET:
public function index($type_id) {
$Product = new Product;
$Product->where('type_id', $type_id);
if(array_key_exists('ages', Input::get())) {
$Product->where('age_id', $_GET['ages']);
}
$products = $Product->get();
$productsPaginated = $Product->where('type_id', $type_id)->paginate(2);
return View::make('products.products', array(
'products' => $products,
'productsList' => $productsPaginated
)
);
}
But all it's doing is bringing back every record.
What am I doing wrong?
This is how I'm rendering my filters:
$brands = $prices = $ages = $brandsUsed = $agesUsed = array();
$out = '';
foreach ($productsList as $product) {
$brands[$product->brands->id] = $product->brands->brand;
$brandsUsed[] = $product->brands->id;
$prices[] = $product->price;
$ages[$product->ages->id] = $product->ages->age;
$agesUsed[] = $product->ages->id;
}
$brandsUsed = array_count_values($brandsUsed);
$brands = array_unique($brands);
$params = Input::get();
$lastParams = http_build_query($params);
unset($params['brand']);
$params = http_build_query($params);
if (count($brands) > 0) {
$out .= '<h5>Brands</h5>';
foreach ($brands as $brandId => $brandName) {
if (stristr($lastParams, '&brand=' . $brandId) || stristr($lastParams, 'brand=' . $brandId)) {
$out .= '<a class="filter-link" href="' . Request::path() . '?' . $params . '">';
} else {
$out .= '<a class="filter-link" href="' . Request::path() . '?' . $params . '&brand=' . $brandId . '">';
}
$out .= '<span class="cbox">';
if (stristr($lastParams, '&brand=' . $brandId) || stristr($lastParams, 'brand=' . $brandId)) {
$out .= '<span class="cbox-checked"></span>';
}
$out .= '</span>';
$out .= $brandName;
$out .= ' (' . $brandsUsed[$brandId] . ')';
$out .= '</a>';
}
}

You cannot create queries on object, you should do it this way:
public function index($type_id) {
$product = Product::where('type_id', $type_id);
if(array_key_exists('ages', Input::get())) {
$product->where('age_id', $_GET['ages']);
}
$productsAll = $product->get();
$productsPaginated = $product->where('type_id', $type_id)->paginate(2);
return View::make('products.products', array(
'products' => $productsAll,
'productsList' => $productsPaginated
)
);
}
You should also consider if it makes any sense to get all products and also paginated products. If you have many products in your database it will take long time to get all your products.
I'm also not sure what exactly you want to get for $productsPaginated. I think you will need here building new query:
$productsPaginated = Product::where('type_id', $type_id)->paginate(2);
EDIT
As you want to get count of products with only one filter, you should use here:
public function index($type_id) {
$product = Product::where('type_id', $type_id);
$productCount = $product->count();
if(array_key_exists('ages', Input::get())) {
$product->where('age_id', $_GET['ages']);
}
$productsPaginated = $product->paginate(2);
return View::make('products.products', array(
'productsCount' => $productCount,
'productsList' => $productsPaginated
)
);
}

Related

How to fix "XML declaration allowed only at the start of the document"

I am trying to generate a sitemap but somehow an extra DIV tag at the initial line of xml. I need to remove this wrong tag DIV from the xml output.
I've tried to gather the logic at first and segregate the generation of the xml side at the bottom.
set header 'text/xml'.
I tried to strip_tags the whole xml string before output, but then, it shows document empty
private function removeImageAndEmbeds ( $content )
{
// remove img tags
$re1='(<img).*?\\/.*?\\/.*?\\/.*?\\/.*?\\/.*?\\/.*?(\\/>)';
if ( $c=preg_replace("/".$re1."/is", "", $content) ) $content = $c;
// remove embedded tags
$re2='(<div).*?(data-oembed-url=)(".*?").*?<\\/div>.*?(<\\/div>)';
if ( $c=preg_replace("/".$re2."/is", "", $content) ) $content = $c;
return $content;
}
public function sitemaps ($tenantName="") {
if ( !empty($tenantName) ) {
$this->db->like( 't.name', str_replace('-', ' ', rawurldecode($tenantName)), 'none' );
$results = $this->db->get($this->TBL . ' t')->result_array();
foreach ( $results as $result ) {
$tenantId = $result['id'];
$tenantNameinURL = formatTenantNameinURL( $result['name'] );
$AllItems = $this->db->get_where($this->DIVIEW . ' di', 'di.account_id = '. $tenantId)->result_array();
$topics = [];
$itemIds = [];
$ddIds = [];
$urls = [];
foreach ( $AllItems as $k => $item ) {
$pieces = explode('_', $item['id']);
if ( $pieces[1] === $this->ITEMTBL ) {
if( !in_array($item['record_id'], $itemIds) ){
$itemIds[] = $item['record_id'];
$content = $this->removeImageAndEmbeds( $item['content'] );
$AllItems[$k]['content'] = $content;
$topics[$k][] = $AllItems[$k];
$urls[$k]['url'] = formatFrontEndURL( $this->current_class_name, $tenantName, 'show', $pieces[0] );
}
} else if ( $pieces[1] === 'dataDefinitions' ) {
if( !in_array($item['record_id'], $ddIds) ){
$ddIds[] = $item['record_id'];
$content = $this->removeImageAndEmbeds( $item['content'] );
$AllItems[$k]['content'] = $content;
$topics[$k][] = $AllItems[$k];
$urls[$k]['url'] = formatFrontEndURL( $this->current_class_name, $tenantName, 'data_definition', $pieces[0] );
}
}
}
$urlset = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset />');
$urlset->addAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
foreach ($topics as $i => $itemsInTopic) {
$url = $urlset->addChild('url');
$url->loc = $urls[$i]['url'];
$pageMap = $url->addChild('PageMap');
$pageMap->addAttribute('xmlns', 'http://www.google.com/schemas/sitemap-pagemap/1.0');
foreach ( $itemsInTopic as $item ) {
$content = $item['content'];
$content = trim( str_replace([" ","\r","\n","\t", "
", "
"], ' ', strip_tags( utf8_decode( $content ) )) );
$dataObject = $pageMap->addChild('DataObject');
$dataObject->addAttribute('type', 'document');
$dataObject->addAttribute('id', $item['record_id']);
$dataObject->Attribute[0]['name'] = 'title';
$dataObject->Attribute[0] = $item['title'];
$dataObject->Attribute[1]['name'] = 'content';
$dataObject->Attribute[1] = $content;
}
}
$xmlContent = $urlset->asXML();
$this->output->set_content_type('text/xml')->set_output( $xmlContent );
}
}
}
here are two errors generated from seochat validator
https://drive.google.com/file/d/1vacmuJL6hnMErzqZ5zZWkkObT74rKOmT/view?usp=sharing
https://drive.google.com/file/d/1y3z85D1WtJIT9GvOC-DeYwS-DtQCAxK5/view?usp=sharing
here is google console error
https://drive.google.com/file/d/1qMvifyjGILqAjJzdWdc90jyymvdUFV5A/view?usp=sharing

echo function inside function bug

I have the following PHP code:
function button1($attr, $text) {
$data = "<button ";
foreach($attr as $names => $specs) {
$data .= $names . "='" . $specs . "' ";
}
$data .= ">" . $text . "</button>\n";
echo $data;
}
function span1($attr, $text) {
$data = "<span ";
foreach($attr as $names => $specs) {
$data .= $names . "='" . $specs . "' ";
}
$data .= ">" . $text . "</span>\n";
echo $data;
}
button1(
array( "type" => "button",
"class" => "navbar-toggle",
"data-toggle" => "collapse",
"data-target" => ".navbar-collapse"
),
span1(
array( "class" => "sr-only" ),
"Toggle navigation"
)
);
From the code above, I want the result to appear like this:
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse' >
<span class='sr-only' >Toggle navigation</span>
</button>
But instead it appears like this:
<span class='sr-only' >Toggle navigation</span>
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse' ></button>
What must I do to get the result I want? Thanks for your help.
Simple, NEVER echo from functions. The problem is, span1() is being evaluate first which results in its echo executing. It also returns nothing to be used as the button1() $text argument. Then the button1() echo is executed, printing its contents to the output stream after the span1() echo.
Change the last line of each function to
return $data;
and execute it via
echo button1(...);
Replace your PHP code with this,
You have to return $data into functions and also echo button1();
<?php
function button1($attr, $text) {
$data = "<button ";
foreach($attr as $names => $specs) {
$data .= $names . "='" . $specs . "' ";
}
$data .= ">" . $text . "</button>\n";
return $data;
}
function span1($attr, $text) {
$data = "<span ";
foreach($attr as $names => $specs) {
$data .= $names . "='" . $specs . "' ";
}
$data .= ">" . $text . "</span>\n";
return $data;
}
echo button1(
array( "type" => "button",
"class" => "navbar-toggle",
"data-toggle" => "collapse",
"data-target" => ".navbar-collapse" ),
span1(
array( "class" => "sr-only" ),
"Toggle navigation"
)
);
Hello use below code for your desired output
function button1($attr, $text)
{
$data = "
foreach($attr as $names => $specs)
{
$data .= $names . "='" . $specs . "' ";
}
$data .= ">" . $text . "</button>\n";
return $data;
}
function span1($attr, $text)
{
$data = "<span ";
foreach($attr as $names => $specs)
{
$data .= $names . "='" . $specs . "' ";
}
$data .= ">" . $text . "</span>\n";
return $data;
}
$str = span1(
array( "class" => "sr-only" ),
"Toggle navigation"
);
echo button1(
array( "type" => "button",
"class" => "navbar-toggle",
"data-toggle" => "collapse",
"data-target" => ".navbar-collapse"
),
$str
);

Flickr API returning duplicate images

I'm trying to get images from flickr using the Flickr API and I'm having trouble figuring out how to get only unique images. I've already reviewed the arguments for the specific method that I'm using and here's what I came up with:
<?php
class Flickr {
private $flickr_key;
private $flickr_secret;
private $format = 'json';
public function __construct( $flickr_key, $flickr_secret ) {
$this->flickr_key = $flickr_key;
$this->flickr_secret = $flickr_secret;
}
public function searchPhotos( $query = '', $tags = '' ) {
$urlencoded_tags = array();
$tags_r = explode(',', $tags);
foreach($tags_r as $tag){
$urlencoded_tags[] = urlencode($tag);
}
$url = 'http://api.flickr.com/services/rest/?';
$url .= 'method=flickr.photos.search';
$url .= '&text=' . urlencode($query);
$url .= '&tags=' . implode(',', $urlencoded_tags);
$url .= '&sort=relevance';
$url .= '&safe_search=1';
$url .= '&content_type=4';
$url .= '&api_key=' . $this->flickr_key;
$url .= '&format=' . $this->format;
$url .= '&per_page=10';
$url .= '&media=photos';
$url .= '&privacy_filter=1';
$result = #file_get_contents( $url );
$json = substr( $result, strlen( "jsonFlickrApi(" ), strlen( $result ) - strlen( "jsonFlickrApi(" ) - 1 );
$photos = array();
$data = json_decode( $json, true );
if($data['stat'] != 'fail'){
$photos = $data['photos']['photo'];
return $photos;
}else{
return false;
}
}
}
And I'll just call it in like:
$flickr = new Flickr($flickr_key, $flickr_secret);
$query = 'Kaspersky Internet Security 2013';
$tags = 'software';
$results = $flickr->searchPhotos($query, $tags);
foreach($results as $img){
$src = "http://farm" . $img['farm'] . ".static.flickr.com/" . $img['server'] . '/' . $img['id'] . '_' . $img['secret'] . '_m.jpg';
?>
<img src="<?php echo $src; ?>"/>
<?php
}
The problem here is that I'm getting duplicate images from time to time.
I also tried using the phpflickr library. But I'm still having the same issues:
$flickr = new phpFlickr($api_key);
$args = array(
'text' => 'Kaspersky Internet Security 2013',
'tags' => 'software',
'per_page' => '10',
'safe_search' => '1',
'content_type' => '4',
'media' => 'photos',
'sort' => 'relevance',
'privacy_filter' => '1'
);
$results = $flickr->photos_search($args);
$hashes = array();
$sources = array();
$images = $results['photo'];
foreach($images as $img){
$src = "http://farm" . $img['farm'] . ".static.flickr.com/" . $img['server'] . '/' . $img['id'] . '_' . $img['secret'] . '_m.jpg';
$current_hash = sha1_file($src);
if(!in_array($current_hash, $hashes)){
?>
<img src="<?php echo $src; ?>" alt="">
<?php
}
$hashes[] = $current_hash;
}
As you can see from the above code I've used sha1_file method to compare the hashes of each of the images returned from flickr. But that's a big performance hit:
without sha1_file: 0.81311082839966
with sha1_file: 6.8974900245667
Any ideas what else can I do to prevent flickr from returning duplicates? As you can see I'm only returning 10 images and that's all I need. I've also tried to add as many arguments that matches my needs but still no luck. Thanks in advance!
try on API explorer, will this give you the same result?
I tried using the param you specified, it returns 34 result in total..

I need to remove duplicates from an array from a specific code

I have the following code:
public function ajax()
{
// Contains results
$data = array();
if( isset($this->request->get['keyword']) ) {
// Parse all keywords to lowercase
$keywords = strtolower( $this->request->get['keyword'] );
// Perform search only if we have some keywords
if( strlen($keywords) >= 3 ) {
$parts = explode( ' ', $keywords );
$add = '';
// Generating search
foreach( $parts as $part ) {
$add .= ' AND (LOWER(pd.name) LIKE "%' . $this->db->escape($part) . '%"';
$add .= ' OR LOWER(p.model) LIKE "%' . $this->db->escape($part) . '%")';
}
$add = substr( $add, 4 );
$sql = 'SELECT pd.product_id, pd.name, p.model FROM ' . DB_PREFIX . 'product_description AS pd ';
$sql .= 'LEFT JOIN ' . DB_PREFIX . 'product AS p ON p.product_id = pd.product_id ';
$sql .= 'LEFT JOIN ' . DB_PREFIX . 'product_to_store AS p2s ON p2s.product_id = pd.product_id ';
$sql .= 'WHERE ' . $add . ' AND p.status = 1 ';
$sql .= ' AND p2s.store_id = ' . (int)$this->config->get('config_store_id');
$sql .= ' ORDER BY LOWER(pd.name) ASC, LOWER(p.model) ASC';
$sql .= ' LIMIT 15';
$res = $this->db->query( $sql );
if( $res ) {
$data = ( isset($res->rows) ) ? $res->rows : $res->row;
// For the seo url stuff
$basehref = 'product/product&keyword=' . $this->request->get['keyword'] . '&product_id=';
foreach( $data as $key => $values ) {
$data[$key] = array(
'name' => htmlspecialchars_decode($values['name'] . ' (' . $values['model'] . ')', ENT_QUOTES),
'href' => $this->url->link($basehref . $values['product_id'])
);
}
}
}
}
echo json_encode( $data );
}
So, the array generates a list of products, like for e.g.:
Apple MacBook (Product Model 10)
Apple МакБук (Product Model 10)
The problem is that those two products is actually one and the same product (same product_id) but in different languages, and both have the same URL.
So, what I want to check is, while making the array, the code to check if there is already a product with that product_id in the array, and if there is, not to add another one with the same product_id.
Practically, I don't want the array to generate two or more products with the same product_id.
EDIT: With Marc's code and ghbarratt suggestion work like a charm. A million thanks to you guys, and to all of you here.
P.S. How can I add ASC or DESC for ORDER BY pd.language_id:
$sql .= ' ORDER BY pd.language_id = ' . (int)$this->config->get('config_language_id');
$sql .= ' , LOWER(pd.name) ASC, LOWER(p.model) ASC';
$data = array();
foreach ($res->rows as $values) {
$data[$values['product_id']] = array(
'name' => ...,
'href' => ...
);
}
Guarantees unique product ids only.
The easiest way should be to add another array to track already written ids and check with http://php.net/manual/en/function.in-array.php:
$basehref = 'product/product&keyword=' . $this->request->get['keyword'] . '&product_id=';
$writtenIds = array();
foreach( $data as $key => $values ) {
if(in_array($values['product_id'], $writtenIds))
{
unset($data[$key]);
continue;
}
$data[$key] = array(
'name' => htmlspecialchars_decode($values['name'] . ' (' . $values['model'] . ')', ENT_QUOTES),
'href' => $this->url->link($basehref . $values['product_id'])
);
$writtenIds[] = $values['product_id'];
}
This answer is similar to Marc's except it will preserve the other names in an additional element on the data array for the product_id and it will make sure to remove the sub-arrays that have the same product_id as the first encountered one, which I believe is an important part of what you wanted to do.
$product_ids_added = array();
foreach( $data as $key => $values ) {
$original_key = array_search($values['product_id'], $product_ids_added);
if($original_key===false) {
$data[$key] = array(
'name' => htmlspecialchars_decode($values['name'] . ' (' . $values['model'] . ')', ENT_QUOTES),
'href' => $this->url->link($basehref . $values['product_id'])
);
$product_ids_added[] = $values['product_id'];
}
else {
unset($data[$key]);
if(!isset($data[$original_key]['additional_names'])) $data[$original_key]['additional_names'] = array();
$data[$original_key]['additional_names'][] = htmlspecialchars_decode($values['name'] . ' (' . $values['model'] . ')', ENT_QUOTES);
}
}

Drupal: Hierarchical taxonomical breadcrumb trail

I'm looking to generate a hierarchical breadcrumb from a taxonomy term (e.g. grandparent/parent/child) when all I have is the TID of "child". I've been toying around with taxonomy_get_tree(), but it seems quite difficult to do without very heavy iteration. There has to be an easier way.
Thoughts?
Thanks!
Taxonomy Breadcrumb seems to provide this functionality.
If you don't want to use the module, the code might provide inspiration.
This is what I do:
$breadcrumb[] = l(t('Home'), NULL);
if ($parents = taxonomy_get_parents_all($tid)) {
$parents = array_reverse($parents);
foreach ($parents as $p) {
$breadcrumb[] = l($p->name, 'taxonomy/term/'. $p->tid);
}
}
drupal_set_breadcrumb($breadcrumb);
I'll typically stick this in a hook_view() function or hook_nodeapi($op="view") function.
If you are using Drupal 7, Taxonomy Breadcrumb is yet in dev version and you have to code.
A solution more complete could be the follow (put this function in YOUR_THEME_NAME/template.php)
function YOUR_THEME_NAME_breadcrumb( $variables )
{
// init
$breadcrumb = $variables['breadcrumb'];
// taxonomy hierarchy
$hierarchy = array();
if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)))
{
$tid = (int)arg(2);
$parents = array_reverse(taxonomy_get_parents_all($tid));
foreach( $parents as $k=>$v)
{
if( $v->tid==$tid ) continue;
$breadcrumb[] = l($v->name, 'taxonomy/term/'. $v->tid);;
}
}
// rendering
if (!empty($breadcrumb))
{
$output = '<h2 class="element-invisible">' . t('You are here') . '</h2>';
$output .= '<div class="breadcrumb">' . implode("<span class='separator'>»</span>", $breadcrumb) . '</div>';
return $output;
}
}
function yourthemename_breadcrumb( $variables )
{// init
$breadcrumb = $variables['breadcrumb'];
// taxonomy hierarchy
$hierarchy = array();
if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)))
{
$tid = (int)arg(2);
$parents = taxonomy_get_parents_all($tid); dpm($parents);
$parents = array_reverse($parents);dpm($parents);
$breadcrumb = array();
$breadcrumb[] = l('Home', '/');
foreach( $parents as $k=>$v)
{
$breadcrumb[] = l($v->name, 'taxonomy/term/'. $v->tid);;
}
}
// rendering
if (!empty($breadcrumb))
{
$output = '<h2 class="element-invisible">' . t('You are here') . '</h2>';
$output .= '<div class="breadcrumb">' . implode("<span class='separator'>»</span>", $breadcrumb) . '</div>';
return $output;
}
}

Categories