Stripping integers from an array - php

I use the following code to strip the product number from a page url so that i can query a database to check for a custom canonical link.
$qs = explode('&',$_SERVER['QUERY_STRING']);
$prodid = explode('=',$qs[0]);
$prod_ID = $prodid[count($prodid)-1];
As an example, $qs contains
Array ( [0] => products_id=1121 [1] => cPath=180_182 [2] => )
I then decided i also needed to be able to specify custom canonicals for the categories as well so i added the following code:
$catid = explode('=',$qs[1]);
$lastnmbr = explode('_',$catid[1]);
$cat_ID = $lastnmbr[count($lastnmbr)-1];
This gives me $prod_ID of 1121 and $cat_ID of 182.
However, here is the problem. If i drop back to the product list rather than a specific product page the array held in $qs becomes Array ( [0] => cPath=180_182 [1] => ) which means that
$catid = explode('=',$qs[1]);
is no longer the correct array position to collect the category id and in fact it is collected by
$prodid = explode('=',$qs[0]);
which makes all the following code think it's a product.
I think i need to somehow use the information held before the = symbol to ensure that if it says cPath it assigns it to $catid and if it says products_id it assigns it to $prodid.
Is there a "correct" way to do this? I did try making a new var of
$catchk = explode($qs[0], '=');
thinking this would return the data BEFORE the = symbol but it didn't so i obviously have the wrong end of the stick here.
To make the solution clear, i used the suggestion from Tyr (Thank you) and finished up with
$catid = $_GET['cPath'];
$lastnmbr = explode('_',$catid);
$cat_ID = $lastnmbr[count($lastnmbr)-1];
$prod_ID = $_GET['products_id'];
It was necessary to be able to strip the set of numbers following the last _ (underscore) as subcategories are shown as 180_182 etc

What if you trying $_GET['product_id'] and $_GET['cPath'] instead of $_SERVER['QUERY_STRING'] usage?
You are avoiding the problems of having the correct array path.

Related

Magento 1 : Removing spaces from column data in collection

i am fetching a product collection and i want to use like condition on custom attribute but the problem is that while using like condition i want to remove all white space contain in my custom attribute value.
i have already tried
$psku = 'some_sku';
$_product = Mage::getModel('catalog/product')->getCollection();
$_product->addFieldToFilter(str_replace(' ', '', 'simple_skus_map'),
array(array('like' => '%,'.$psku.',%'),
array('like' => '%,'.$psku),
array('like' => $psku.',%'),
array('like' => $psku)
));
// simple_skus_map : (my custom attribute has data like one, two, three ,four). and i want the following code should fetch all the product which simple_skus_map contains any of the above mentioned word(i.e one/two/three/four)
NOTE: noticed? i have spaces in my custom attribute.
for custom attribute you can do as following, hence it will remove white space from your custom attribute value and match the given/post data
$_product = Mage::getModel('catalog/product')->getCollection();
$_product->addExpressionAttributeToSelect('trimmed_simple_skus_map',
'REPLACE({{simple_skus_map}},\' \',\'\')','simple_skus_map');
$_product->addFieldToFilter('trimmed_simple_skus_map', [
'finset' => [$psku]
]
);
The query as you supplied can perform slow, as it uses like with wildcards. You can use the find_in_set functionality.
Luckily magento supports this as well:
$_product = Mage::getModel('catalog/product')->getCollection();
// Trim spaces, 'save to column' trimmed_simple_skus_map
$_product->addExpressionAttributeToSelect('trimmed_simple_skus_map', 'REPLACE(sku,\' \',\' \')', 'simple_skus_map');
// Find in trimmed set
$_product->addFieldToFilter('trimmed_simple_skus_map', [
'finset' => [$psku]
]
);
I have another solution, with direct SQL queries.
here is the php code:
$resource = Mage::getSingleton('core/resource');
$readConnection = $resource->getConnection('core_read');
$writeConnection = $resource->getConnection('core_write');
$q_find_blank = "SELECT *FIELD_NAME* FROM simple_skus_map WHERE *FIELD_NAME* LIKE '% %'; ";
$results = $readConnection->fetchAll($q_find_blank); //get all field with a blank space
foreach ($results as $result){ //set all the fields in array and removes the blanks
$result = explode(' ',$result);
$no_blanks_fields[] = implode("",$result);
}
echo print_r($no_blanks_fields);
foreach ($no_blanks_fields as $no_blanks_field){ //replace them in the database field
echo $no_blanks_field . "<br>";
$q_update = "UPDATE simple_skus_map set *FIELD_NAME* = ".$no_blanks_field." WHERE *condition referencing the right field to his value*";
$writeConnection->query($q_update);
}
this is simply, not very high performance, but works.
Just remember when you write data make sure to set the correct value in the correct fields (you can maybe creating a temporary support table, with |field|id| ).
This will remove your blanks from the selected field, and replace them with a non blanks value(or whatever you want to implode them with, just check the implode function).
"test field blanks" => "testfieldsblanks"

how to avoid duplicate slugs when saving a friendly url

sorry but I'm new, a true apprentice of the php. Sorry for my English, but I'm Italian.
I'm trying to figure out how to avoid saving duplicates in the slug column of my database when I save.
When I save a new page I check in the database if I find a line with the slug I would like to save. If it is not there, I proceed without problems. If there is instead I would like to save it by adding "1" and then "2" and so on.
I'v tried with
$string="example-2";
$string= str_replace("-", "", $string);
$string=filter_var($string, FILTER_SANITIZE_NUMBER_INT);
and works but but if I save a slug like this:
$string="my2example-2";
It' doesn't work
I can not understand how to do in php to analyze the string and understand if there is already a number at the end of the string.
Example:
the first time i save a sulg 'example'.
Then I want to save a second page with the "exemple" slug, so I look in the database, I find that there is "exemple" then I add "-1" to my string and save it as "example-1".
Then I want to save "exemple" again, I find it exists "example". So i have to search to look for "exemple-1"
How to do it?
and than how do I then identify what number I have arrived to save
"exemple-2"?
thanks
You should keep the original slug then each time you check the DB for an existing entry append -1, -2 etc until you get no matches.
$i = 1;
$baseSlug = $slug;
function slug_exists($slug) {
$query = "SELECT `slug` FROM `table` WHERE `slug`=?";
$stmt = $dbl->prepare($query);
$stmt->bind_param("s", $slug);
$stmt->execute();
if ($stmt->num_rows > 0) {
return true;
} else {
return false;
}
}
while(slug_exist($slug)){
$slug = $baseSlug . "-" . $i++;
}
// Save slug in DB
Instead of querying your database to determine if slug example exists, you can get all slugs that starts with example:
SELECT slug FROM table WHERE slug LIKE 'example%';
Then you just need to filter out values that aren't example or example-[0-9]+. In some databases you can do it directly, but you can also do it with regex in PHP. Last thing is to find slug with highest number (for example by sorting first), and incrementing the numeric part.
Ensure that you're using natural sort ordering
Example from above link:
<?php
$array1 = $array2 = array("img12.png", "img10.png", "img2.png", "img1.png");
asort($array1);
echo "Standard sorting\n";
print_r($array1);
natsort($array2);
echo "\nNatural order sorting\n";
print_r($array2);
?>
results:
Standard sorting
Array
(
[3] => img1.png
[1] => img10.png
[0] => img12.png
[2] => img2.png
)
Natural order sorting
Array
(
[3] => img1.png
[2] => img2.png
[1] => img10.png
[0] => img12.png
)

PHP - Pulling array and splitting the strings

Not sure how to title this properly but here's the issue I am running into currently. I built a cart and checkout system and it loads all the data into a database when it finalized the order. To save some space, I stored just the item IDs originally but then I ran into the issue of if I deleted the item from the database (because it was discontinued or whatever) then it wouldn't return the info I needed. And if they ordered more then 1 item the database record would be wrong. So I stored the data like so:
Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2
OR
1:3:20.00:Flower Hat, 2:1:17.75:diamonds
The issue I have right now that I need help with is this. I need to seperate the four values into variables like $price, $item, $id, $ammount so I can display them on the order history page and I need to loop through all items on the array so I can print a row for each item with all four fields respective to that item.
I use strpos already to get the shipping info from the same database field which is formatted as METHOD:Price but since I have 3 :'s on my string I'm not sure how to go through each one. Thanks.
Here's a function
function parseItems($dbjunk){
$cart = array();
$items = explode(",",$dbjunk);
foreach($items as $i){
$chunks = explode(":", $i);
$cart[] = array(
"ItemID" => $chunks[0] ,
"Quantity" => $chunks[1] ,
"Price" => $chunks[2] ,
"name" => $chunks[3]
);
}
return $cart;
}
Example usage:
$dbjunk = "Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2";
$parsed = parseItems($dbjunk);
print_r($parsed);
See: https://3v4l.org/rBkXF
If you need variables instead of an array you can use list(), like this..
$dbjunk = "Itemid:Quantity:Price:name, itemid2:quantity2:price2:name2";
$parsed = parseItems($dbjunk);
foreach($parsed as $p){
list($itemID, $Quantity, $Price, $name) = array_values($p);
var_dump($itemID, $Quantity, $Price, $name);
}
see: https://3v4l.org/l4vsn
You should not physically delete items from your database. Instead, put a new column named 'is_active' or something like that to indicate whether the product is active/non-deleted.
Answering your question, here is my suggestion:
$orderString = '1:3:20.00:Flower Hat, 2:1:17.75:diamonds';
$items = array();
foreach(explode(', ', $orderString) as $itemString) {
$itemData = explode(':', $itemString);
$items[] = array(
'id' => $itemData[0],
'amount' => $itemData[1],
'value' => $itemData[2],
'description' => $itemData[3]
);
}
with this code, you will obtain an array with the data of all the items in the string, no matter how much items are in the string
try something like
$data = 1:3:20.00:Flower Hat, 2:1:17.75:diamonds
list($price, $item, $uid, $id, $ammount) = explode(":", $data);
echo $user;
echo $item;
Read about First Normal Form. Basically, you want to store one value in one field. So, instead of this:
shipping = "method:price"
You want something like this:
shipping_method = "method"
shipping_price = "price"
Don't concern yourself with space -- it's essentially free nowadays.
Regarding your deleted items dilemma, your initial implementation was the way to go:
I stored just the item IDs originally
In addition to reverting to this technique, I would recommend two things:
Add a boolean field to your item table to represent if the item is currently available or not. This gives you the additional feature of being able to toggle items on/off without having to delete/insert records and change ids.
Before deleting an item, check to see if it's ever been ordered. If not, it's ok to delete. If so, instead just deactivate it.

Using Valve/Steam API to get multiple IDs converted

So this is a VERY long explanation.
I have a Counter-Strike: Source server, with an in-game plugin for a store. This store saves its data in a MySQL Database (for this instance, named 'store'). The store keeps track of player's money in that database (on column 'credits' in table 'users'). It stores the clients based on a 'steam_id' (unique to every client)
The format of a 'steam_id' is (example): STEAM_0:0:123456789 OR STEAM_0:1:12345789.
My page that I have displays the top 1000 users from the database (sorted by credits).
My Problem: I need to convert these ugly steam_id's to actual names.
Where I am right now:
Steam API Documentation
According to the API documentation, I have to use 'community ids' when I query the API. If I want to get more than one user, I can use commas to separate community ids in the GET string.
(http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=APIKEY&steamids=76561197960435530,76561197960435531&format=json)
I have a function that converts the steam_id's to API-acceptable ID's.
function SteamID2CommunityID($steam_id){
$parts = explode(':', str_replace('STEAM_', '' ,$id));
$communityID = bcadd(bcadd('76561197960265728', $parts['1']), bcmul($parts['2'], '2'));
return $communityID;
}
With that, I can make my list of comma separated community ids with this:
while ($row = $mysqli->fetch_assoc($request)) {
$ids .= ',' . SteamID2CommunityID($row['steamid']) . ',';
}
Now for the tricky part, all these values come back in one JSON array. I need to add something, so when I display my data, I can convert a 'steam_id' straight to a 'name' (with the existing array).
Example of an output (most keys & values are removed to make it readable)
Array (
[response] => Array
(
[players] => Array
(
[0] => Array
(
[steamid] => 76561198010207577
[personaname] => [rGA] Stainbow
)
[1] => Array
(
[steamid] => 76561197966653036
[personaname] => |K}{R|Mastarious(MNBH)
)
)
)
)
So again, how would I go about going straight from a 'steam_id' to a name?
Thank you to anybody who can provide code and/or suggestions!
This is a variant duplicate of another Stack Overflow question, which is more practical and less localized, but I might as well answer this.
Assuming that your input steam_id is $INPUT and your final output array is stored in $OUTPUT, this is the functional foreach approach that you could use to convert steam_id to personaname:
/**
* Convert steam_id to personaname
* #returns STRING The name associated with the given steam_id
* BOOL FALSE if no match was found
*/
function steamID_to_name($INPUT, $OUTPUT)
{
// This gets the relevant part of the API response.
$array = $OUTPUT['response']['players'];
// Using your function to convert `steam_id` to a community ID
$community_id = SteamID2CommunityID($INPUT);
// Linear search
foreach ($array as $array_item)
{
// If a match was found...
if ($community_id == $array_item['steamid'])
// Return the name
return $array_item['personaname'];
}
// If no match was found, return FALSE.
return false;
}

How do I check and unset/set SESSION by element?

I have a session var for a shopping cart that reads: 'cart_b_1_1'.
The letter in the string indicates a category, the ints represent user id & product id.
How can I check the category of an already set SESSION var to see if it matches the category of a new selection?
I am trying to make sure that if an item is added to the SESSION array and there is a var that already exists with the same category letter, then it is unset and effectively replaced with the new selection. This is to limit selections by category to one.
Thanks for the help in advance.
You should consider taking advantange of the awesomeness of what associative arrays let you do:
$_SESSION['categories'][$mycat] = array($user_id, $product_id);
That way whenever you set a new category it overrides the last one. Not sure why you need the user_id at that level, assuming the whole cart belongs to one user, my Session would look like:
array(
'user' => $user_id,
'cart' => array('catid' => 'prodid', 'catid2', 'prodid2'))
);
You should use 3 variables instead of 1.
$_SESSION['category'] = 'cart_b';
$_SESSION['user_id'] = 1;
$_SESSION['product_id'] = 1;
But just in general - you can convert string to a array with '_' separator.
$varArray = explode('_', $_SESSION['var']);
explode the session variable using _ and check the first element to find the category.
$myarray=explode("_",$_SESSION['yourvariablename']);
then you the $myarray[1] is the category so you can compare and do other stuff.
Is this what you wanted?

Categories