I'm a PHP developer who typically uses arrays in lieu of objects, and I'd like to know if there are any best practices for object manipulation based on key values.
Take the following multi-dimensional array of events, typical of something you'd pull directly out of the database.
$events = array(
0=>array(
'eventid'=>1,
'title'=>'First Event',
'date'=>'20131010'
),
1=>array(
'eventid'=>2,
'title'=>'Second Event',
'date'=>'20131022'
),
2=>array(
'eventid'=>3,
'title'=>'Third Event',
'date'=>'20131010'
),
),
For display purposes in my template, I want to make this a multi-dimensional array based on the date first. This is fairly easy transformation that I use a helper function for.
assoc($events,'date','eventid');
Resulting in:
$events = array(
20131010=>array(
1 => array(
'eventid'=>1,
'title'=>'First Event',
'date'=>'20131010'
),
3 => array(
'eventid'=>3,
'title'=>'Third Event',
'date'=>'20131010'
),
),
20131022=>array(
2 => array(
'eventid'=>1,
'title'=>'First Event',
'date'=>'20121010'
),
),
),
In this way, I can easily run through the array on the template side for each date, create a header and for that date, and then display events for that day underneath.
I could go ahead and try to make a similar assoc() function for Objects, but it strikes me this should be a fairly common thing and there may be a standard way of doing it. If you had an object instead of an array for $events, how would you go about formatting it the second way I've described, or would you?
One additional piece of information: I am using CodeIgniter, in case it has some helper functions that I'm not aware of that could be useful.
In your assoc function you could do an is_object check and cast to an array if it is an object.
function your_assoc_func($events){
if(is_object($events)){
$events = (array)$events
}
// If the object is more complex cast any containing objects you may run across
foreach($events as $event){
if(is_object($event)){
$event = (array)$event
}
}
}
Related
I am working with the Church Community Builder API (official docs, search for "group profile" to see relevant code) and with CCB Core WordPress Plugin to sync groups data from the API into custom post types (fields, taxonomies).
CCB Core maps a lot of this data automatically, but it doesn't map the group ID value CCB uses to distinguish one group from another and I'd like to sync it.
The relevant code is kept in the functions get_groups_custom_fields_map() and get_groups_taxonomy_map().
I've tried adding something like the following to get_groups_taxonomy_map():
'group_id' => array (
'api_mapping' => 'group',
'data_type' => 'integer',
),
But this doesn't work. Any suggestions on writing code to pull in this field?
UPDATE 9/10/16 7:25 PM:
I think I am wicked close.
I took the XML from the API documentation under Group Profile and ran it through simplexml and generated this output.
I then compared the output with how the get_groups_custom_fields_map and get_groups_custom_taxonomy_map was organized, which led me to believe the following should work:
'group' => array (
'api_mapping' => 'group',
'data_type' => 'object',
'child_object' => array(
'api_mapping' => '#attributes',
'data_type' => 'object',
'child_object' => array(
'group_id' => array(
'api_mapping' => 'id',
'data_type' => 'integer'
)
)
)
),
But it doesn't. What am I missing?
The SimpleXML representation of the response that comes back from CCB just so happens to have a really frustrating way of deserializing the IDs for the entities (Groups, Events, Individuals, etc) that come out of the API. (And it only happens on the IDs).
Even though Group ID looks like a property in the XML response string, it's actually an attribute which is slightly different. In your object response, notice that # symbol in the [#attributes] node. PHP will not allow direct access to that.
See "At sign" # in SimpleXML object?
As a workaround I actually obtain the Group ID like so right here:
https://github.com/jaredcobb/ccb-core/blob/1a6e88b47ad7d5293e88bac277e72cbc4e33a602/admin/class-ccb-core-sync.php#L589-L595
Code snippet of the above reference:
$group_id = 0;
foreach( $group->attributes() as $key => $value ) {
if ( $key == 'id' ) {
$group_id = (int) $value;
break;
}
}
So in general, we do have access to that group id, we just need to now save it as post meta. I'll update the plugin to take advantage of these IDs, but in the mean time you can use the $group_id variable directly and save the post meta in this function.
I try to store a function inside an array but it keeps giving me this error:
unexpected 'function' (T_FUNCTION)
I looked around on internet but they mostly say that I should be using php version 5.3 and above, while I am using 5.6.21.
Here is my array:
static $Events = array(
'View Page' => array(
'properties' => array(
'previous_event',
'number_view_page',
),
'trigger' => function($foo){
return $foo;
},
),
);
If anyone knows what the problem is and how to solve it, please help me :)
static values need to be initialised with static/constant expressions. Sadly, anonymous functions aren't "constant" enough to count. Later PHP versions allow some limited expressions like 2 + 4 (because the result is always constant), but nothing more than that. Function declarations are too complex to handle in a static context (you can add a function to the array afterwards at any time, you just can't initialise it that way*).
* The reason for this restriction is that static declarations are handled at a different parsing phase than runtime code, and that parsing phase cannot handle anything but primitive values.
Try again with this (you have 2 ,, too much at the end of the code and please remove the static)
EDIT: adding function so you can use the array from other class.
function $events_func()
{
$events = array(
'View Page' => array(
'properties' => array(
'previous_event',
'number_view_page',
),
'trigger' => function($foo){
return $foo;
}
)
);
return $events;
}
I have a little REST API in my project. And ofcourse i use json as my return data to work with.
I am using symfony in the backend and angularJs in the frontend. At the moment i convert my entity to json by looping true my result and filling an data array to return as json.
EXAMPLE:
public function getAction($id)
{
$em = $this->getDoctrine()->getManager();
$warehouseId = $this->get('session')->get('warehouse');
$warehouse = $em->getRepository('BubbleMainBundle:Warehouse')->find($warehouseId);
$trip = $em->getRepository('BubbleMainBundle:Trip')->find($id);
$data = array(
'id' => $trip->getId(),
'driver' => $trip->getDriver(),
'status' => $trip->getStatus(),
'date' => $trip->getPlanningDate()->format('Y-m-d')
);
if ( count($trip->getStops()) > 0 ) {
foreach($trip->getStops() as $stop)
{
$data['assignedStops'][] = array(
'id' => $stop->getId(),
'status' => $stop->getStatus(),
'date' => $stop->getDeliveryDate()->format('Y-m-d'),
'sort' => $stop->getSort(),
'company' => array(
'name' => $stop->getToCompany()->getName(),
'lat' => $stop->getToCompany()->getLat(),
'lng' => $stop->getToCompany()->getLng(),
'address' => $stop->getToCompany()->getAddress(),
'zip' => $stop->getToCompany()->getZip()
),
);
}
} else {
$data['assignedStops'][] = '';
}
$response = new jsonResponse();
$response->setData($data);
return $response;
}
This works. But sometimes i have have (google chrome timeline) waiting responses of 6 seconds for just a simple query and json response.
Is looping true the entity to much? Or do i need another approach for converting my entities to json format?
thx anthony,
If you are using PHP 5.4 or above then considering using the JsonSerializable interface with your entities:
http://www.php.net/manual/en/class.jsonserializable.php
This will allow you to control how your entities are converted to JSON which will allow you to call json_encode directly on your entities without having to loop through and convert them to arrays.
As for the performance issue you'd need to profile your script to find out where the performance bottleneck is. From looking at your code one potential issue that you might want to look into is to make sure you are fetching all the data in your original query (i.e stops and companies) and you are not executing additional queries in the foreach loop to fetch the missing stop and company data.
I recommend you (since you are using Symfony2 as a backend and you need an API) to definitely try out this bundle... It's easy to use and to setup and as an extra you can also generate a nice documentation for it.
It will speed up your development and code.
I created a custom Drupal module and now want to save some preferences for it. Those are essentially 3 arrays of strings that should be saved and also easily edited by a (administrative) user.
What would be the best way to do that in Drupal? I've read about variable_set and variable_get, are they appropriate to store module-specific data like this?
Is there some way to easily create an admin form to edit those variables, or do I have to write that from scratch?
If you want to do it fast, use variable_get/set and system_settings_form().
Need more space than a comment. #yorirou has the correct answer. However, to store/retrieve an array of strings each entered by different widgets, you have an easy path:
Wrap everything in a fieldset with the #tree property. All fields within that fieldset will be folded into an array structured based on the fieldset name for the variable name, and the individual field names for the key value. Array serialization is automatically handled on variable_get/set.
$form['custom_settings'] = array(
'#title' => t('My settings'),
'#type' => 'fieldset',
'#tree' => TRUE,
);
$form['custom_settings']['first_setting'] = array(
'#type' => 'textfield',
// etcetera
);
$form['custom_settings']['second_setting'] = array(
'#type' => 'textfield',
// etcetera
);
On output of the saved array, you would get something like this:
custom_settings = Array(
'first_setting' => 'some string',
'second_setting' => 'some other string',
)
You could get the same affect with a #validate handler, or using the #parents element in the forms arrays, but those would require extra work to wrangle the default value.
I have a Thrift php client and I want to write in a HBase table and I'm doing the following:
$mutations = array(
new Mutation( array(
'column' => 'entry:num',
'value' => array('a','b','c')
) ),
);
$client->mutateRow( $t, $row, $mutations );
The problem is that when inserting in HBase the value, which is an array, gets converted to 'Array' instead of storing the elements of the array.
How can I store the list as an array (or byte array)
A HBase mutation object has required three fields with boolean/text values, not arrays. So you need to turn any structured value into a string, something like.
$mutations = array(
new Mutation( array(
'isDelete' => FALSE,
'column' => 'entry:num',
'value' => serialize(array('a','b','c'))
) ),
);
$client->mutateRow( $t, $row, $mutations );
The definition of the HBase Thrift API is here;
http://svn.apache.org/viewvc/hbase/trunk/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift?view=markup
I haven't tested this.
I must admit that I do not have a clue what you're trying to do (perhaps due to a lack of knowledge regarding Thrift and HBase), but if I understood your question correctly, you're trying to write some PHP data structure (array in this case) to a storage media. To achieve this you have to serialize your data somehow. That could be using a custom XML serialization, a custom binary serialization or, perhaps the most simple solution, the PHP internal serialization mechanism provided by serialize() and the corresponding unserialize().
If you strive for inter-language-interoperability you should use a custom serialization or you have to write a unserialization function that unserializes the PHP serialization format in your target language.
Just a quick example - I don't know where you'd have to put this code, as I don't know exactly what you're doing:
$mutations = array(
new Mutation(array(
'column' => 'entry:num',
'value' => array('a','b','c')
)),
);
$data = serialize($mutations); // $data now is a string
// write $data to storage
// read $readData from storage
$readMutations = unserialize($readData);
// $readMutations == $mutations
// (but the Mutation instances are not the same instances any more)
Please seee
serialize()
unserialize()
Serializing objects - objects in sessions