Problem with accessing class members as an array in PHP class - php

I'm trying to integrate the FedEx tracking class into my application. The class takes a SOAP response and puts it into a hierarchical class structure. I access the values like this:
$city = $response->TrackDetails->Events[$i]->Address->City;
This works fine for most cases. The problem I am having is when there is just one event for a given shipment, I get an error saying that I cannot treat the class as an array. Since there is just one event, I need to access it without the array index using:
$city = $response->TrackDetails->Events->Address->City;
Is there a way to deal with this without doing something like this:
if($num_events==1){
$city = $response->TrackDetails->Events->Address->City;
}else{
$city = $response->TrackDetails->Events[$i]->Address->City;
}
There are a ton of data fields that fall into this issue, so I don't want to use something so cumbersome if I can avoid it. Any ideas?

if ($num_events == 1) {
$response->TrackDetails->Events = array($response->TrackDetails->Events);
}
This can be done with a loop over all the fields in your answer, automatically putting each loner into an array of length 1.

Related

Number of rows in getItems

I was trying to get all the items from a list using the phpSPO library: https://github.com/vgrem/phpSPO
However in the $remoteList properties in the array of Data there are only 100 rows, and the list has more than 100 items. I saw that it's a common problem, however I don't know which solution I should consider for this library.
https://sharepoint.stackexchange.com/questions/74777/list-api-get-all-items-limited-to-100-rows
$remoteList = $web->getLists()->getByTitle(xxx)
$listData = $remoteList->getItems();
There's a public property for the CamlQuery class called ListItemCollectionPosition defined in this file:
https://github.com/vgrem/phpSPO/blob/b05be0eba6902dabd18784576bb6e1d55426fa99/src/SharePoint/CamlQuery.php
That expects a ListItemCollectionPosition object as a value: https://github.com/vgrem/phpSPO/blob/b05be0eba6902dabd18784576bb6e1d55426fa99/src/SharePoint/ListItemCollectionPosition.php
So I think your code will need to look something like:
$remoteList = $web->getLists()->getByTitle(xxx);
$listItemCollectionPosition = new new ListItemCollectionPosition(); // Either add a use statement for this or use the fully qualified class name here
// ... (set the values according to the items/page you require)
$remoteList->ListItemCollectionPosition = $listItemCollectionPosition;
$listData = $remoteList->getItems();
In terms of how to use it exactly, have a read of the information here:
https://learn.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee534956(v%3Doffice.14)#retrieving-items-using-list-item-collection-position
The example is in C# but it's not too hard to follow.
It looks as though you set the ListItemCollectionPosition on your query to get subsequent "pages". It also looks as though responses include a ListItemCollectionPosition property themselves that you can then use as a starting point for the next request.

Why does Laravel saves each field as "true" when presenting the datas in an array?

So, I have the following code:
$homepage = Homepage::first();
if (!$homepage) {
$homepage = new Homepage;
}
$homepage->first_presta_title = $request->first_presta_title;
$homepage->first_presta_content = $request->first_presta_content;
$homepage->second_presta_title = $request->second_presta_title;
$homepage->second_presta_content = $request->second_presta_content;
$homepage->third_presta_title = $request->third_presta_title;
$homepage->third_presta_content = $request->third_presta_content;
$homepage->shiatsu_text = $request->shiatsu_text;
$homepage->shiatsu_image = $request->shiatsu_image;
$homepage->doin_text = $request->doin_text;
$homepage->doin_image = $request->doin_image;
$homepage->save();
Everything works, but I wanted to see if there weren't any better way to save datas without asigning every single element to its column, then I found out someone answering to a question by using the following code:
$homepage->save($request->all());
So I tried it by myself, but nothing happened: no error, but also nothing saved in my database.
So, is there any fastest way to save datas ? Is it possible to use a loop to save everything?
Thank you in advance
When you use save(), you are actually using Mass assignment. So, either you explicitly define all the fields in your model to be mass assignable or you could use create() instead.
However, in your particular case, the whole method could be cleaned up to just one line:
return Homepage::updateOrCreate($request->all());
If you want the model to autofill based on a given array you need to create a new model entity Like this
$homepage = HomePage::create($request->all());
$homepage->save()
If you give an array to save() it expects the options for saving not for values to assign
Source:
laravel api docs for model/save()
laravel api docs for model::create()

Is there an easier way to iterate through a list of objects properties in Laravel

I have a Laravel app where I am using a bit of code which feels really unintuitive.
In the code I return a list of objects ($occupied) which all have the the column 'property'. I then go on to create an array of the list of objects 'property's ($occupiedproperty) just to use it in a whereNotIn call.
if ($occupied = Residency::currentResidents()){
// Here is the pointless part //////
$occupiedproperty = array();
foreach ($occupied as $occ) {
array_push($occupiedproperty, $occ->property);
}
///////////////////////////////////
return Property::whereNotIn('id', $occupiedproperty)->get();
}
This code works fine to do the job but creating a new array when I already have a list of objects seems lazy. I tried looking at eloquent's documentation but I couldn't figure this out.
I need to be able to access the 'property' column of $occupied so I can run something like whereNotIn('id', $occupied->property)
Thank you
Can't test it right now, but this should work (it should work even without casting to array the $occupied collection):
$occupiedProperties = array_pluck((array)$occupied, 'property');
It uses the array_pluck() helper method: http://laravel.com/docs/4.2/helpers#arrays

Zend Framework - How to modify a single parameter from the request object

A submitted form on my site returns an array of request data that is accessible with
$data = $this->getRequest();
This happens in the controller which gathers the data and then passes this array to my model for placing/updating into the database.
Here is the problem. What if I want to manipulate one of the values in that array? Previously I would extract each value, assigning them to a new array, so I could work on the one I needed. Like so:
$data = $this->getRequest();
$foo['site_id'] = $data->getParam('site_id');
$foo['story'] = htmlentities($data->getParam('story'));
and then I would pass the $foo array to the model for placing/updating into the database.
All I am doing is manipulating that one value (the 'story' param) so it seems like a waste to extract each one and reassign it just so I can do this. Additionally it is less flexible as I have to explicitly access each value by name. It's nicer to just pass the whole request to the model and then go through getting rid of anything not needed for the database.
How would you do this?
Edit again: Looking some more at your question what I am talking about here all goes on in the controller. Where your form`s action will land.
Well you have a couple of options.
First of all $_GET is still there in ZF so you could just access it.
Second there is:
$myArray = $this->_request->getParams();
or
$myArray = $this->getRequest()->getParams();
Wich would return all the params in an array instead of one by one.
Thirdly if the form is posted you have:
$myArray = $this->_request()->getPost();
Wich works with $this->_request->isPost() wich returns true if some form was posted.
About accessing all that in your view you could always just in controller:
$this->view->myArray = $this->_request->getParams();
edit: right I taught you meant the view not the model. I guess I do not understand that part of the question.
If you want to deal with the post data inside your model just:
$MyModel = new Model_Mymodels();
$data = $this->_request->getParams();
$data['story'] = htmlentities($data['story']);
$myModels->SetItAll($data);
And then inside your model you create the SetItAll() function (with a better name) and deal with it there.
Edit: oh wait! I get it. You hate sanytising your input one by one with your technique. Well then what I showed you about how to access that data should simplify your life a lot.
edit:
There is always the Zend_Form route if the parameters are really coming from a form. You could create code to interface it with your model and abstract all this from the controller. But at the end of the day if you need to do something special to one of your inputs then you have to code it somewhere.

Getting database values into objects

The thing is that you have classes and then you have the database data. When you create an object how do you set the objects properties to contain the data in the database ?
I saw something like this and I'm wondering if this is really the best way to do it. I'm sure this is a fairly common issue, but I don't know what are the most accepted solutions on how to handle it.
In this example when the object is created you pass an id as a parameter and then you run a query to the database with the id and you assing the returned values to the object properties. I don't have much PHP experience and haven't seen this used much.
Is this an acceptable way to achieve this purpose ? Is there a better or more accepted way ?
public function __construct($id = null){
if($id != null){
$sql = "SELECT *
FROM users
WHERE user_id = $id";
$res = Db::returnRow($sql);
// $res contains an associative array with database columns and values
if($res){
$this->user_id = $res['user_id'];
$this->user_name = $res['user_name'];
//and so on...
}
}
}
Could somebody provide some sample code or pseudocode to illustrate what is the correct way to do this ?
It could be an acceptable way for a homework maybe. But architecturaly it is not.
Your class that is representing your business data (a user in your example) must be loosely coupled with your database access logic. In the end the PHP class acting as a user should not be aware that the data come from a database, a file or any other resource. Following that you will be able to reuse your user php class in other projects without having to change anything to it! If you have your data access logic inside it you are stuck.
Conclusion: I would suggest to read some resources on Design Pattern (in your situation take a look at DAO pattern) ;) Hint: the one from Head First series is extremely accessible and enjoyable.
You could create a function to do this for you automatically, by looping over the associative array's key/value pairs. Or you could look into using an ORM library.
Yes, you can semi-automate this by having a parent class all objects inherit from. On load, it queries, "SHOW FIELDS FROM [my tablename]" and populates an associative array with the names. If an id has been passed in, it looks for a valid object in that table with that id and assigns the values to the array.
Side note: don't pass your id directly into your query like that. Parametize the sql and wrap a function around any user input to sanitize it.
If it's mysql, you can just do:
$obj = mysql_fetch_object($query);
PDO the ability to use arbitrary classes as the target for a fetch, but beware that they assign the variable data before running the constructor:
$pdo->query($stmt, PDO::FETCH_CLASS, "MyClass", array('foo'=>'bar'));
...where the final parameter contains arguments for your class constructor.

Categories