explode column from database - php

Hi every I need to get product from the database and explode it in one line of code So I can get product data and get product_properties as an array together
$Product = Product::find(33);
$properties = explode(",", ($Product ->product_properties));

You could just explode product_properties to get an array or, you could also define an accessor on your Product model.
So in App\Product, add the following:
public function getPropertiesAttribute()
{
return explode(',', $this->product_properties);
}
That's it. Now, every time you retrieve your model, you also have access to its properties in an array format by doing the following:
$product = Product::find(33);
$product->properties; // will output product_properties in an array format
Edit: If you want this properties (computed) field to be included in its JSON representation, for example, you need to define it in the appends property in your model. For example.
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = ['properties'];
Here's a working example.

You can achieve it doing:
$properties = explode(",", (Product::find(33)->product_properties));
But this is poor in readability compared with your first approach.

Related

how to map collection in php laravel

i want return data if a < b then a = b, if using foreach i have to make empty array first and parsing data to te empty array, how if record i much, that take time
public function getDepreciation(){
$values = $this->repository->getDepreciation();
$data = [];
foreach($values as $value){
if($value->depresiation_per_month > $value->balance_value){
$value->depresiation_per_month = $value->balance_value;
}
array_push($data,$value->depresiation_per_month,$value->balance_value);
}
return $data;
}
is there is simple code than my above, since i have to make relist many array
You can convert this array in a Collection then handle it easier by using the transform method.
First you have to create the collection using your array Create Collection
$values = collect($values);
Then you can iterate over the collection using the transform method and apply your logic Transform Method
Finally you have to convert your collection into an array using the toArray method toArray Method
I hope this works for you

Laravel get model without appends attributes

I'm working with Laravel 5.3 and in a Model Post, I have an appends attributes :
/*
* toJson
*/
protected $appends = ['count'];
And the magic method :
public function getCountAttribute()
{
return Offer::where('id', '=', $this->id)->count();
}
So, when I get a Post model with eloquent like Post::get(), and get the return with json for example, I ALWAYS have this attribute count in my object.
How can I specify if I want or not this or another appends atribute ?
I checked how Eloquent models get serialized and unfortunately list of fields to be appended is not shared between all instances of given Model and the only way I see to achieve what you need is to iterate through the result set and explicitly enable append for selected attributes:
$posts = Post::all();
foreach ($posts as $post) {
// if you want to add new fields to the fields that are already appended
$post->append('count');
// OR if you want to overwrite the default list of appended fields
$post->setAppends(['count']);
}
You could get the model's attributes with $post->getAttributes() which returns an array of attributes before any appends

Using column names when generating JSON in Propel

When using toJSON() on an ObjectCollection the names of the properties are always based on the PHP-names. For instance:
For the column type_name the JSON property becomes TypeName, etc.
Is there a way to make Propel use the name of the field/column instead?
If you don't mind using json_encode, try using the object's toArray() with arguments:
use Map\AuditTableMap as TableMap;
$something = new Something();
$something->setSomeColumnValue("value");
echo json_encode($something->toArray(SomethingMap::TYPE_FIELDNAME));
Output:
{"some_column_value": "value"}
In other words, use the argument <ObjectName>Map::TYPE_FIELDNAME to output an array with column names.
The docs are amazing, but they're quite confusing to navigate. I found the following comment from one of the generated models in my project. This is for version 2.0#dev, which I'm using; note that it may differ in your version. (I'd suggest looking at the docs for more formal guidance, but you can take a peek at your models too.)
/**
* Exports the object as an array.
*
* You can specify the key type of the array by passing one of the class
* type constants.
*
* #param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_CAMELNAME,
* TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM.
* Defaults to TableMap::TYPE_PHPNAME.
* #param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE.
* #param array $alreadyDumpedObjects List of objects to skip to avoid recursion
* #param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE.
*
* #return array an associative array containing the field names (as keys) and field values
*/
If you only want to strictly use the toJSON call, then you'll have to do some post-processing manipulation of the string, because the only option allowed with the toJSON method is to include or not include lazy-loaded columns.
$something = new Something();
$something->setSomeColumnValue("value");
$json = $something->toJSON();
$tableMap = \Propel::getDatabaseMap()->getTableMap('Something');
$columnMaps = $tableMap->getColumns();
$phpNames = array();
$columnNames = array();
foreach ($columnMaps as $columnMap) {
$phpNames[] = '"' . $columnMap->getPhpName() . '"';
$columnNames[] = '"' . $columnMap->getColumnName() . '"';
}
$json = str_replace($phpNames, $columnNames, $json);
One caveat to this code is that if the value matches one of your column names exactly, it will be replaced. The only way to eliminate this is to json_decode the JSON object and only replace the keys, but if you don't want to use json_encode, I don't suppose you'd want to use json_decode.
#Cezille07's answer is the most correct in this case. My answer is mainly to show how TableMap/ColumnMaps can be used for post-processing, which is something I didn't know about when I started with Propel.

How to execute a closure function and populate an array passed by reference in PHP

I am trying to use PHP closures for the first time.
I wrote a small function that will take an array and a function in it's parameter. Its job is to loop through the giving array and it executes the $function on each element.
Here is my function
/**
* It check each item in a giving array for a property called 'controllers',
* when exists it executes the $handler method on it
*
* #param array $items
* #param function $handler
*/
protected function addSubControls($items, $handler)
{
foreach( $items as $item){
if( property_exists($item, 'controllers')){
//At this point we know this item has a sub controller listed under it, add it to the list
foreach($item->controllers as $subControl){
$handler( $subControl );
}
}
}
}
Now I want to use this function in 2 ways.
First: execute the method generateHtmlValues() on every item within the giving array. This works with no issues.
$this->addSubControls($control->items, function($subControl){
$this->generateHtmlValues( $subControl );
});
Second: I want to add each qualifying item to an array that is being used outside that closure method.
$controls = ['a','b','c'];
$this->addSubControls($control->items, function($subControl) use(&$controls) {
$controls[] = $subControl->id;
});
var_dump($controls);
at this point I am expecting that the $controls array to have 1 more value that what the original one is set to. But it is not doing that.
What am I missing here? How can the closure populate the array that I pass by reference?
After all, my code works correctly.
I was looking at the wrong output.
I will keep this question hoping it will help someone else.

Cleanest way of dealing with different argument types

I have the following piece of code, which generates six drop-down elements:
for($i = 0; $i < 6; $i++)
{
$RelatedProductsHtmlList .= $this->getRelatedProductHtmlDropdown($Products[$i], $allAvailibleProducts, $i);
}
In this code, the argument $Products[$i] is passed, which is a ORM object with information for setting the default selected value of the drop-down list that is generated. I have the problem that $Products is not always an array. Sometimes only contains one value, in which case it's not an array, but a single ORM object.
What is the cleanest thing to do? Convert $Products to an array with only one element? Always pass the entire $Products variable en determine in the function if it's an array? Or determine if $Products is an array before calling the function and set the function argument accordingly?
You have two options: fix it before calling the method or inside the method itself.
Example:
if(!is_array($products)) {
$products = array($product));
}
If you ask me, I would add this code to the top of the method itself as this would ease the function call and reduce redundant code.
I would suggest to allow to pass array and a single object into a function. You will avoid multiple checks in different parts of code. You can do it this way:
/**
#param array | ProductClass $Products
...
*/
public function getRelatedProductHtmlDropdown($Products, $allAvailibleProducts, $i)
{
if (!is_array($Products)) $Products = array($Products);
....
}

Categories