Related
I'm getting data by CakePHP findbyList
Array
(
[92] => 5
[93] => 5
[98] => 5
)
CODE
$get = array(
'fields' => array('Upload.type'),
'joins' => array(
array(
'alias' => 't',
'table' => 'temp_files',
'type' => 'LEFT',
'conditions' => array('Upload.id = t.file_id')
),
array(
'alias' => 'o',
'table' => 'orders',
'type' => 'LEFT',
'conditions' => array('o.batch_id = t.batch_id')
)
),
'conditions' => array('OR'=>array('o.user_id '=>$user['id'],'t.user_id '=>$user['id'])),
'group' => 'Upload.id'
);
$files = $this->find('list',$get);
Is there any way in CakePHP for getting data like:
Array
(
[5] => Array
(
[0] => 92
[1] => 93
[2] => 98
)
)
Yes, there is two cakephp ways to retrive results like yours:
Find threaded:
https://book.cakephp.org/2.0/en/models/retrieving-your-data.html#find-threaded
and use Hash utility to extract, combine , etc your results:
https://book.cakephp.org/2.0/en/core-utility-libraries/hash.html
Without knowing how your database looks like I would probably use $this->find('all',$get) instead of 'list'
List will always put the ID of your model as a key, so it will never work as you need.
It would have been much better to understand this situation if db structure would have been mentioned.
Anyways what I would suggest is to to use $this->find('all',$get) instead of list and you can play around your final result array by managing the way you need your final output array.
EX:- if you get the list of the user name with userID then you are using CakePHP collection in CakePHP query.
CakePHP collection here :CakePHP Collection
$userList = $this->find()
->where(['status' => Configure::read('Status.active')])
->order(['first_name' => 'ASC'])
->combine('id','name')
->toArray();
in this result in userID is a key and name as a value display.
I try to make a web application for my thesis.
Actually it is almost finished but I still have to find a way to store the likes of users in a database. I collect user information and try to see if there is a relation between movies that he or she like and user data elements that are saved in different SNSs. For single information it already save the things the way it should be. The problem is, that facebook work with arrays and objects and I am not able to find a way to save all the likes in a single string (and then save it in a database).
// Insert or update user data to the database
$fbUserData = array(
'oauth_provider' => 'facebook',
//basic profile
'oauth_uid' => $fbUserProfile['id'],
'first_name' => $fbUserProfile['first_name'],
'last_name' => $fbUserProfile['last_name'],
'picture' => $fbUserProfile['picture']['url'],
'email' => $fbUserProfile['email'],
'link' => $fbUserProfile['link'],
'age_range' => $fbUserProfile['age_range']['min'],
'currency' => $fbUserProfile['currency']['user_currency'],
'devices' => $fbUserProfile['devices'],//['hardware']
'gender' => $fbUserProfile['gender'],
'install_type' => $fbUserProfile['install_type'],
'installed' => $fbUserProfile['installed'],
'is_shared_login' => $fbUserProfile['is_shared_login'],
'is_verified' => $fbUserProfile['is_verified'],
'locale' => $fbUserProfile['locale'],
'name_format' => $fbUserProfile['name_format'],
'payment_pricepoints' => $fbUserProfile['payment_pricepoints'], //credits?
'security_settings' => $fbUserProfile['security_settings']['secure_browsing']['enabled'],
'test_group' => $fbUserProfile['test_group'],
'timezone' => $fbUserProfile['timezone'],
'updated_time' => $fbUserProfile['updated_time'],
'verified' => $fbUserProfile['verified'],
'video_upload_limits' => $fbUserProfile['video_upload_limits']['size'],
'viewer_can_send_gift' => $fbUserProfile['viewer_can_send_gift'],
//extended permissions
'relationship_status' => $fbUserProfile['relationship_status'],
'hometown' => $fbUserProfile['hometown']['name'],
'languages' => $fbUserProfile['languages'][0]['name'].",".$fbUserProfile['languages'][1]['name'].",".$fbUserProfile['languages'][2]['name'].",".$fbUserProfile['languages'][3]['name'].",".$fbUserProfile['languages'][4]['name'],
//'likes' => $fbUserProfile['likes'][0]['name'].",".$fbUserProfile['likes'][1]['name']
'favorite_athletes' => $fbUserProfile['favorite_athletes'][0]['name'].",".$fbUserProfile['favorite_athletes'][1]['name'].",".$fbUserProfile['favorite_athletes'][2]['name'].",".$fbUserProfile['favorite_athletes'][3]['name'].",".$fbUserProfile['favorite_athletes'][4]['name'].",".$fbUserProfile['favorite_athletes'][5]['name'].",".$fbUserProfile['favorite_athletes'][6]['name'],
);
$userData = $user->checkUser($fbUserData);
//print
echo $userData['languages'];
echo $userData['favorite_athletes'];
As you can see for languages, likes, favorite_athletes I coded it in the ugly way now to read the profile and store it. The problem is that some people have over 100 likes, and it is of course not handy to code it in this way. When I use the
for each it always bug...
If you're just interested in concatenating arrays for a single table then use PHPs implode function http://php.net/manual/en/function.implode.php
combined with an array map as mentioned here
How to use implode on an array of stdClass objects?
alternatively normalise your database as mentioned in a comment
'favorite_athletes' => implode(",", array_map(function($x) { return $x['name'];},$fbUserProfile['favorite_athletes']));
'likes' => implode(",", array_map(function($x){ return $x['name']}, $fbUserProfile['likes']['data']));
// Insert or update user data to the database
$fbUserData = array(
'oauth_provider' => 'facebook',
//basic profile
'oauth_uid' => $fbUserProfile['id'],
'first_name' => $fbUserProfile['first_name'],
'last_name' => $fbUserProfile['last_name'],
'picture' => $fbUserProfile['picture']['url'],
'email' => $fbUserProfile['email'],
'link' => $fbUserProfile['link'],
'age_range' => $fbUserProfile['age_range']['min'],
'currency' => $fbUserProfile['currency']['user_currency'],
'devices' => $fbUserProfile['devices'][0]['hardware'],
'gender' => $fbUserProfile['gender'],
'install_type' => $fbUserProfile['install_type'],
'installed' => $fbUserProfile['installed'],
'is_shared_login' => $fbUserProfile['is_shared_login'],
'is_verified' => $fbUserProfile['is_verified'],
'locale' => $fbUserProfile['locale'],
'name_format' => $fbUserProfile['name_format'],
'payment_pricepoints' => $fbUserProfile['payment_pricepoints'], //credits?
'security_settings' => $fbUserProfile['security_settings']['secure_browsing']['enabled'],
'test_group' => $fbUserProfile['test_group'],
'timezone' => $fbUserProfile['timezone'],
'updated_time' => $fbUserProfile['updated_time'],
'verified' => $fbUserProfile['verified'],
'video_upload_limits' => $fbUserProfile['video_upload_limits']['size'],
'viewer_can_send_gift' => $fbUserProfile['viewer_can_send_gift'],
//extended permissions
'relationship_status' => $fbUserProfile['relationship_status'],
'hometown' => $fbUserProfile['hometown']['name'],
'languages' => implode(",", array_map(function($x) { return $x['name'];},$fbUserProfile['languages'])),//$fbUserProfile['languages'][0]['name'].",".$fbUserProfile['languages'][1]['name'].",".$fbUserProfile['languages'][2]['name'].",".$fbUserProfile['languages'][3]['name'].",".$fbUserProfile['languages'][4]['name'],
'likes' => implode(",", array_map(function($x){ return $x['name'];}, $fbUserProfile['likes']['data'])),
'favorite_athletes' => implode(",", array_map(function($x) { return $x['name'];},$fbUserProfile['favorite_athletes']))
I am experimenting with WriteRequestBatch from AWS SDK for Dynamodb. Below is my code. Everything works except the WriteRequestBatch part. I have no clue why, and was wondering if the community could help me out here. What might I be doing wrong? I have tried googling and searching here and found only 8 other questions that could be related but unfortunately were of no help.
This is where I started from.
$ddb_client = DynamoDbClient::factory(array(
'region' => 'us-east-1',
'key' => 'my_key',
'secret' => 'my_secret'
));
$ddb_client->createTable(array(
'TableName' => 'my_table',
'AttributeDefinitions' => array(
array(
'AttributeName' => 'id',
'AttributeType' => 'S'
),
array(
'AttributeName' => 'ns',
'AttributeType' => 'S'
)
),
'KeySchema' => array(
array(
'AttributeName' => 'id',
'KeyType' => 'HASH'
),
array(
'AttributeName' => 'ns',
'KeyType' => 'RANGE'
)
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
));
$response = $ddb_client->putItem(array(
"TableName" => "my_table",
"Item" => array(
"id" => array("S" => "exp_id"),
"ns" => array("S" => "exp_ns"),
"version" => array("N" => "0"),
),
));
$item = $response['Item'];
$item['version']['N'] = '1';
$put_batch = WriteRequestBatch::factory($ddb_client);
$put_request = new PutRequest(
array(
"Item" => $item,
"Expected" => array(
"version" => array(
"ComparisonOperator" => "EQ",
"AttributeValueList" => array(
array("N" => "0")
)
),
),
),
"my_table"
);
$putBatch->add($put_request);
$putBatch->flush();
This works instead of WriteRequestBatch. I will just have to manage batches to put myself than use WriteRequestBatch doing it for me:
$response = $ddb_client->batchWriteItem(array(
"RequestItems" => array(
"my_table" => array(
array(
"PutRequest" => array(
"Item" => $item,
"Expected" => array(
"version" => array(
"ComparisonOperator" => "EQ",
"AttributeValueList" => array(
array("S" => "0")
)
),
),
)
)
)
)
));
The answer by Geek Stocks is incomplete, but still helpful. One thing you can do handle the asynchronous aspects of the CreateTable operation is to use a Waiter:
$ddb_client->createTable(array('TableName' => 'my_table', ... ));
$ddb_client->waitUntil('TableExists', array('TableName' => 'my_table'));
However, there is also a problem with how you are using the WriteRequestBatch class. When you create a PutRequest, you must pass in the item, not a whole set of PutItem parameters. The WriteRequestBatch is an abstraction over DynamoDB's BatchWriteItem operation, which does not allow things like the Expected parameter. If you want to do that, then you need to use individual PutItem/UpdateItem/DeleteItem requests.
Here is a modified version of your usage of WriteRequestBatch that is correct:
$putBatch = WriteRequestBatch::factory($ddb_client);
$putBatch->add(new PutRequest($item, 'my_table'));
// ADD MORE...
// ...
// ...
$putBatch->flush();
Here is another example of using the WriteRequestBatch from the SDK's User Guide.
EDIT: One more complete example that works that I just tested, that shows the difference between versions prior to 2.7.0 and afterwards
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Model\BatchRequest\WriteRequestBatch;
use Aws\DynamoDb\Model\BatchRequest\PutRequest;
use Aws\DynamoDb\Model\Item;
$client = DynamoDbClient::factory([/* ... */]);
$batch = WriteRequestBatch::factory($client);
for ($i = 1; $i <= 55; $i++) {
// FOR ANY SDK VERSION
// (NOTE: Does not support new M, L, BOOL, and NULL types)
$item = Item::fromArray(['id' => $i, 'data' => "foo{$i}"]);
// FOR SDK >= 2.7
$item = ['id' => ['N' => $i], 'data' => ['S' => "foo{$i}"]];
$batch->add(new PutRequest($item, 'my-table'));
}
$batch->flush();
Because you currently do not have any "try / catch" error handling around your code you are likely not getting good information on your error.
I placed try/catch blocks on your code and found that the table creates just fine but that the call to putItem fails for the following reason: Requested resource not found
When you create a table it is NOT immediately available. You have to pause until it becomes available. This paragraph of the AWS docs explains this nicely:
CreateTable is an asynchronous operation. Upon receiving a CreateTable request, DynamoDB immediately returns a response with a TableStatus of CREATING . After the table is created, DynamoDB sets the TableStatus to ACTIVE . You can perform read and write operations only on an ACTIVE table. You can use the DescribeTable API to check the table status.
Once you add the call to DescribeTable like it shows, you should be good.
Taking a sub panel in sugarcrm and making it into two, one that displays entries depending if a checkbox is checked, the other non checked entries.
I have a module called mod_loaninvestor, and its sub panel is whole_subpanel_mod_loaninvestor_contacts
Now I know vardefs is where you create the duplicate and rename it like this
<?php
//WARNING: The contents of this file are auto-generated
// created: 2014-01-24 13:12:28
$layout_defs["Contacts"]["subpanel_setup"]['mod_loaninvestor_contacts'] = array (
'order' => 100,
'module' => 'mod_LoanInvestor',
'subpanel_name' => 'default',
'sort_order' => 'asc',
'sort_by' => 'id',
// 'where' => "(mod_LoanInvestor.active_investment == "1")",
'title_key' => 'LBL_MOD_LOANINVESTOR_CONTACTS_FROM_MOD_LOANINVESTOR_TITLE',
'get_subpanel_data' => 'mod_loaninvestor_contacts',
'top_buttons' =>
array (
/*
0 =>
array (
'widget_class' => 'SubPanelTopButtonQuickCreate',
),
1 =>
array (
'widget_class' => 'SubPanelTopSelectButton',
'mode' => 'MultiSelect',
),
*/
),
);
// created: 2014-01-24 13:12:28
$layout_defs["Contacts"]["subpanel_setup"]['mod_loaninvestor_contacts1'] = array (
'order' => 100,
'module' => 'mod_LoanInvestor',
'subpanel_name' => 'default',
'sort_order' => 'asc',
'sort_by' => 'id',
'title_key' => 'LBL_MOD_LOANINVESTOR_CONTACTS_FROM_MOD_LOANINVESTOR_TITLE',
'get_subpanel_data' => 'mod_loaninvestor_contacts',
'top_buttons' =>
array (
/*
0 =>
array (
'widget_class' => 'SubPanelTopButtonQuickCreate',
),
1 =>
array (
'widget_class' => 'SubPanelTopSelectButton',
'mode' => 'MultiSelect',
),
*/
),
);
?>
How would I make it so the first one would only show entries with the following checked
and the other display only entries with that field unchecked?
Thanks for your help!
You're halfway there. On top of defining new layoutdefs, you need to create a new subpanel definition.
Dig into mod_LoanInvestor and the metadata/subpanels/default.php and copy it to default2.php or whatever you'd like to call it. You'll want to use a WHERE clause to separate the two.
https://gist.github.com/matthewpoer/8871568
Here's a gist where I'm doing this with transactions records to seperate scheduled (future) transactions from past (posted payments).
I am using Cakephp 2.2.4 and I need to retrive a list of Lead that belongs to the user (id = 106).
The result of the query is:
array(
(int) 0 => array(
'Lead' => array(
'id' => '6',
'user_id' => '106',
'date' => '2012-12-31 22:15:23',
'ip' => '127.0.0.1',
'service_id' => '1',
'location' => 'Rome',
'message' => 'Message Message',
'telephone' => null,
'active' => null
),
'User' => array(
'id' => '106',
'email' => 'daje#daje.it',
'pwd' => '0433c024cb08be13000d59a347e640482843f46f177e95749dc6599c259617fd3491dcb940b47693cbbc7f65a2cc5ef62deca2e600c1be133ad54170f7d1fbd1',
'role_id' => '3',
'active' => '1'
),
'Service' => array(
'id' => '1',
'name' => 'Primo servizio'
),
'Estimate' => array(
(int) 0 => array(
'id' => '1',
'lead_id' => '6',
'user_id' => '106'
)
)
)
)
It looks good but I need to count the Estimates (Estimate array), I would like to retrive the number of the estimates, and not the array with all the fields (of estimates table).
How can i do it?
I need :
Lead array as it shown
User array as it shown
Service array as it shown
Estimate (only the total number of the estimates... in this case 1)
The find is very simple:
$options = array('conditions' => array('User.id' => 106));
debug($this->Lead->find('all', $options));
Try something like this, not 100% sure it'll work but worth a go if not I'd advise trawling the cakephp docs for retrieving your data:
$options = array(
'fields' => array('Lead.*', 'User.*', 'Service.*', 'count(Estimate.id)'),
'conditions' => array('User.id' => 106)
);
Without diving too far into the internals of the Cake ORM, assuming you don't need to do this immediately at query time, couldn't you just get the count of the estimate array programmatically after the fetch?
http://php.net/manual/en/function.count.php
$leads = $this->Lead->find('all',$options);
foreach($leads as $lead){
//get the number of estimates for every lead result
$lead_num = count($lead['Estimate']);
}
Alternatively, you could manually write a join query for this one fetch and execute it using the Cake Model class's query method. Without knowing the specifics of your table schema and model relations its hard to give specifics about how to structure the query, but this shouldn't be too difficult by just look at your table spec and extracting a sql COUNT statement for every Estimate with given id.