Programmatically speaking, is there a way to fetch an array or collection of SugarCRM bean objects?
That is, let's say I wanted to fetch a number of account rows that included the word Bank in their name. With raw SQL, I'd do something like this
SELECT *
FROM Accounts
WHERE name LIKE '%Associates%`;
Is there a way using the SugarCRM ORM to so something similar? If not, how do SugarCRM programmers typically handle this situation? I realize I could hack something together by selecting a list of IDs from the database
$db = DBManagerFactory::getInstance();
$result = $db->query('SELECT id FROM Accounts where name LIKE "%Banking%"');
$accounts = array();
while($row = $db->fetchRow($result))
{
$accounts[] = BeanFactory::getBean('Accounts', $row['id']);
}
but in most ORM's that would be considered inefficient, and bad practice. Is there a better way?
(Perfectly ready for the answer to be "No, there's not way to do that". I'm new to the platform and trying to get my bearings)
Rather use
$bean = BeanFactory::getBean('Accounts');
$account_list = $bean->get_full_list("", "accounts.name like '%Associates%'");
As get_list will give you what you have defined for list_max_entries_per_page.
Here is a great resource for different ways to use the standard SugarBean versus SQL: here
For your example:
$bean = BeanFactory::getBean('Accounts');
$account_list = $bean->get_list("", "accounts.name like '%Associates%'");
This is an old question but for future readers, SugarBean methods get_list() and get_full_list() seem to be deprecated and it is advised to use SugarQuery instead.
$bean = BeanFactory::getBean('Accounts');
$query = new SugarQuery();
$query->from($bean, array('team_security' => false));
$query->where()->contains('name', 'Associates');
$account_list = $query->execute();
Related
I'm updating a site from pear DB to MDB2, I've managed to get quite far but I've come unstuck on a query I'm not sure what they are trying to achieve here.
Can anyone explain.
Here it is
$bookRes = $mdb2->query(("SELECT * FROM book WHERE (".join(' OR ', $sqlParams).") $categorySQL ORDER BY title"), $sqlValues);
while ($row = $bookRes->fetchRow()) {
$row['type'] = 'book';
$booksPossibles[] = $row;
}
I would need to see a bit more of the code to be sure, but this appears to be a simple dynamic generation of a SELECT statement where various criteria, with placeholders, stored in the $sqlParams array are being added to the WHERE clause and the values for those criteria are specified in the $sqlValues variable, again presumably an array.
so $sqlParams and $sqlValues might look like:
$sqlParams = array("val1 > ?", "val2 = ?");
$sqlValues = array(2, 4);
(It helps to know that the join keyword in PHP is just an alias for implode.)
$query = "SELECT * FROM Name";
works perfectly as expected but:
$query = "SELECT * FROM Name WHERE name = 'david'";
doesn't work as expected. The DataStore is created as follows:
$obj_name = new Entity();
$obj_name->name = strtolower($name);
$obj_name->age = $age;
$result = $obj_name_store->upsert($obj_name);
Any suggestions for how to extract a specific item using GQL?
Thank you.
It looks like you are using my php-gds library from here: https://github.com/tomwalder/php-gds
If so, then the problem is likely that you have not explicity requested the "name" property be indexed by Datastore.
When defining your Schema, you need to pass the optional second parameter "TRUE" in order for queries to work against those fields.
See here for a code example.
https://github.com/tomwalder/php-gds#defining-your-model
I have an object that has a single comment on it and then that object has subobjects that each can have a comment on it. As it is today I have a single variable to store the comment on the whole object and a list to store the comments for the objects subobjects.
public $TestResultComments = array();
public $Comment;
Now I not only want to store the plain text of a comment but also store the username of that person that has wrote it and the timestamp. So instead of the single variable $Comment I now want to store three. What is the best way to store this, into an array or is there something similar as in Haskell where there are Tuples?
$comment = odbc_result($result, "comment");
$userName = odbc_result($result, "username");
$timeStamp = odbc_result($result, "timestamp");
$testResult->Comment = $comment;//This is what I do today, but I also want to include $userName and timestamp here
The second part is where I store the comments for the subobjects.
for ($i = 1; $i <= $no_results; $i++) {
odbc_fetch_row($result, $i);
$type = trim(odbc_result($result, "result"));
$testResult->TestResultComments[$type] = trim(odbc_result($result, "comment"));//Here I aswell want to store "comment","username" and "timestamp" as they are called in the database table and not only "comment" as I currently do.
}
As you can see in the second example I have a keyvalue "result" to get the comment. Here I also want to get the values ("comment","username","timestamp") instead of a single value as today.
Thanks in advance.
Seems like a nice situation to use the stdClass. stdClass allows you to dynamically declare fields for an object. You have an array of these, with say result as the key.
Example
$allValues = array();
// Create the values.
$values = new stdClass();
$values->comment = $comment;
$values->username = $username;
$values->timestamp = $timestamp;
$allValues[$result] = $values;
This gives you a direct mapping from a $result to several values, in a clean and OOP way. In the future, assuming you've created $result, you can say..
$values = $allValues[$result];
echo "The username is ". $values->username;
I really like using it because it makes your code super clean and OOP in syntax. For loosely typed languages like PHP, readability can sometimes be lost so it's important you maintain practises like this to keep things easy to understand.
To help everyone understand what I'm asking I put forward a scenario:
I have user A on my web app.
There is a particular page which has a table that contains information that is unique to that user. Let's say it is a list of customers that only show for user A because user A and these customers are in region 5.
Other users are assigned to different regions and see different lists of customers.
What I would like to do is cache all of the results for each users list. This isn't a problem as I can use:
$MC = new Memcache;
$MC->addserver('localhost');
$data = $MC->get('customers');
if($data)
{
} else {
$data = $this->model->customersGrid($take, $skip, $page, $pageSize, $sortColumn, $sortDirection, $filterSQL, $PDOFilterParams);
$MC->set('customers', $data);
}
header('Content-Type: application/json');
return $data;
The challenge now is to somehow convert the SQL filter syntax that comes from my users table into a function that can filter and sort an array ($data is a JSON string that I would turn into an array if that's the right way to go).
Just for reference, here is the array of aliases I use for building the WHERE clause in my statements:
$KF = new KendoFilter;
$KF->columnAliases = array(
'theName' => 'name',
'dimensions' => 'COALESCE((SELECT CONCAT_WS(" x ", height, width, CONCAT(length, unit)) FROM products_dimensions,
system_prefs, units_measurement
WHERE products_dimensions.productId = product.id
AND units_measurement.id = system_prefs.defaultMeasurementId), "-")',
'gridSearch' => array('theName', 'basePrice')
);
$filterSQL = $KF->buildFilter();
My question is what is a good way to filter and sort memcache data as if it was an SQL query? Or does memcache have something already built in?
Memcache cannot do this - you can't replace your database with memcache (that is not what it is for), you can only store key => value pairs.
I think a better approach is to store each data for each user in a specific mem cache key.
So for example if user A with $user_id = 123 visits the page:
$data = $MC->get('customers_for_'.$user_id);
This way you only get the customers for user 123.
A more generic approach is to generate a hash for each sql query with it's params (but that might be overkill in most cases). For example if you have a query select ... from ... where a = #a and b = #b with variables $a and $b you could do the following (you must adapt this for kendo of course, but to get the idea):
$query = "select ... from ... where a = #a and b = #b";
# crc32 because it is fast and the mem key does not get too long
$sql_crc = crc32($query.$a.$b);
$data = $MC->get("customers_".$sql_crc);
To rule out (unlikely) hash collisions for different users, you could mix in the user id in the key, too:
$data = $MC->get("customers_for_".$user_id."_".$sql_crc);
BUT: If you start doing this all over the place in your app because otherwise it is too slow, then maybe the problem lies in your database (missing/wrong indexes, bad column definitions, complicated relations, etc.) and time should better be invested in fixing the DB than working around the issue like this.
Ok, so I am slowly migrating from Procedural to OOP, and I'm finding it all pretty straight forward apart from one thing.
I used to use this method for pulling my settings data from a simple two-column settings table comprising of a row for each setting, defined with 'setting' and 'value' fields:
$query = mysql_query("SELECT * FROM `settings`");
while ($current_setting = mysql_fetch_array($query)) {
$setting[$current_setting['setting']] = $current_setting['value'];
}
As you can see, I manipulated it so that I could simply use $setting['any_setting_name'] to display the corresponding 'value' within that setting's row. I'm not sure if this is a silly way of doing things but no matter, I'm moving on anyway..
However, since moving to object orientated PHP, I don't really know how to do something similar..
$query = $mysqli->query("SELECT * FROM `settings`");
while ($current_setting = $query->fetch_object()) {
echo $current_setting->setting; // echo's each setting name
echo $current_setting->value; // echo's each setting value
}
As you can see, I'm perfectly able to retrieve the data, but what I want is to be able to use it later on in the form of: $setting->setting_name; which will echo the VALUE from the row where setting is equal to 'setting_name'..
So basically if I have a row in my settings table where setting is 'site_url' and value is 'http://example.com/', I want $setting->site_url; to contain 'http://example.com/'.. Or something to the same effect..
Can anyone help me out here? I'm at a brick-wall right now.. Probably something really stupid I'm overlooking..
Since you are working with a resource it has a pointer. Once you get to the end you can't use it anymore. I think you can reset it but why not mix the new with the old?
I don't think you're going to have too much overhead, any that matters anyway, to do something like this:
$settings = array();
$query = $mysqli->query("SELECT * FROM `settings`");
while ($current_setting = $query->fetch_object()) {
$settings[$current_setting->setting] = $current_setting->value;
}
Now you can use $settings as much as you want.
UPDATE
Haven't tested this or used it but are you looking to do something like this? Consider the following pseudo code and may not actually work.
$settings = new stdClass();
$query = $mysqli->query("SELECT * FROM `settings`");
while ($current_setting = $query->fetch_object()) {
$settings->{$current_setting->setting} = $current_setting->value;
}