$bean = BeanFactory::newBean('<TheModule>');
//For example a new account bean:
$accountBean = BeanFactory::newBean('Accounts');
Beans are the Model in SuiteCRM’s MVC (Model View Controller) architecture. They allow retrieving data from the database as objects and allow persisting and editing records. This section will go over the various ways of working with beans.
The BeanFactory allows dynamically loading bean instances or creating new records. For example to create a new bean you can use:
$bean = BeanFactory::newBean('<TheModule>');
//For example a new account bean:
$accountBean = BeanFactory::newBean('Accounts');
Retrieving an existing bean can be achieved in a similar manner:
$bean = BeanFactory::getBean('<TheModule>', $beanId);
//For example to retrieve an account id
$bean = BeanFactory::getBean('Accounts', $beanId);
getBean
will return an unpopulated bean object if $beanId
is not
supplied or if there’s no such record. Retrieving an unpopulated bean
can be useful if you wish to use the static methods of the bean (for
example see the Searching for Beans section). To deliberately retrieve
an unpopulated bean you can omit the second argument of the getBean
call. I.e.
$bean = BeanFactory::getBean('<TheModule>');
BeanFactory::getBean
caches ten results. This can cause odd behaviour
if you call getBean
again and get a cached copy. Any calls that return
a cached copy will return the same instance. This means changes to one
of the beans will be reflected in all the results.
Using BeanFactory ensures that the bean is correctly set up and the necessary files are included etc.
The SugarBean is the parent bean class and all beans in SuiteCRM extend this class. It provides various ways of retrieving and interacting with records.
The following examples show how to search for beans using a bean class. The examples provided assume that an account bean is available names $accountBean. This may have been retrieved using the getBean call mentioned in the BeanFactory section e.g.
$accountBean = BeanFactory::getBean('Accounts');
The get_list method allows getting a list of matching beans and allows paginating the results.
get_list(
$order_by = "",
$where = "",
$row_offset = 0,
$limit=-1,
$max=-1,
$show_deleted = 0)
$order_by
Controls the ordering of the returned list. $order_by
is specified
as a string that will be used in the SQL ORDER BY clause e.g. to sort
by name you can simply pass name
, to sort by date_entered descending
use date_entered DESC
. You can also sort by multiple fields. For
example sorting by date_modified and id descending
date_modified, id DESC
.
$where
Allows filtering the results using an SQL WHERE clause. $where
should be a string containing the SQL conditions. For example in the
contacts module searching for contacts with specific first names we
might use contacts.first_name='Jim'
. Note that we specify the table,
the query may end up joining onto other tables so we want to ensure
that there is no ambiguity in which field we target.
$row_offset
The row to start from. Can be used to paginate the results.
$limit
The maximum number of records to be returned by the query. -1 means no limit.
$max
The maximum number of entries to be returned per page. -1 means the default max (usually 20).
$show_deleted
Whether to include deleted results.
get_list will return an array. This will contain the paging information and will also contain the list of beans. This array will contain the following keys:
list
An array of the beans returned by the list query
row_count
The total number of rows in the result
next_offset
The offset to be used for the next page or -1 if there are no further pages.
previous_offset
The offset to be used for the previous page or -1 if this is the first page.
current_offset
The offset used for the current results.
Let’s look at a concrete example. We will return the third page of all
accounts with the industry Media
using 10 as a page size and ordered
by name.
$beanList = $accountBean->get_list(
//Order by the accounts name
'name',
//Only accounts with industry 'Media'
"accounts.industry = 'Media'",
//Start with the 30th record (third page)
30,
//No limit - will default to max page size
-1,
//10 items per page
);
This will return:
Array
(
//Snipped for brevity - the list of Account SugarBeans
[list] => Array()
//The total number of results
[row_count] => 36
//This is the last page so the next offset is -1
[next_offset] => -1
//Previous page offset
[previous_offset] => 20
//The offset used for these results
[current_offset] => 30
)
get_list
is useful when you need paginated results. However if you are
just interested in getting a list of all matching beans you can use
get_full_list
. The get_full_list
method signature looks like this:
get_full_list(
$order_by = "",
$where = "",
$check_dates=false,
$show_deleted = 0
These arguments are identical to their usage in get_list
the only
difference is the $check_dates
argument. This is used to indicate
whether the date fields should be converted to their display values
(i.e. converted to the users date format).
The get_full_list call simply returns an array of the matching beans
Let’s rework our get_list
example to get the full list of matching
accounts:
$beanList = $accountBean->get_full_list(
//Order by the accounts name
'name',
//Only accounts with industry 'Media'
"accounts.industry = 'Media'"
);
Sometimes you only want to retrieve one row but may not have the id of
the record. retrieve_by_string_fields
allows retrieving a single
record based on matching string fields.
retrieve_by_string_fields(
$fields_array,
$encode=true,
$deleted=true)
$fields_array
An array of field names to the desired value.
$encode
Whether or not the results should be HTML encoded.
$deleted
Whether or not to add the deleted filter.
Note here that, confusingly, the deleted flag works differently to the other methods we have looked at. It flags whether or not we should filter out deleted results. So if true is passed then the deleted results will not be included.
retrieve_by_string_fields returns a single bean as it’s result or null if there was no matching bean.
For example to retrieve the account with name Tortoise Corp
and
account_type Customer
we could use the following:
$beanList = $accountBean->retrieve_by_string_fields(
array(
'name' => 'Tortoise Corp',
'account_type' => 'Customer'
)
);
If you have used one of the above methods we now have a bean record. This bean represents the record that we have retrieved. We can access the fields of that record by simply accessing properties on the bean just like any other PHP object. Similarly we can use property access to set the values of beans. Some examples are as follows:
//Get the Name field on account bean
$accountBean->name;
//Get the Meeting start date
$meetingBean->date_start;
//Get a custom field on a case
$caseBean->third_party_code_c;
//Set the name of a case
$caseBean->name = 'New Case name';
//Set the billing address post code of an account
$accountBean->billing_address_postalcode = '12345';
When changes are made to a bean instance they are not immediately
persisted. We can save the changes to the database with a call to the
beans save
method. Likewise a call to save
on a brand new bean will
add that record to the database:
//Get the Name field on account bean
$accountBean->name = 'New account name';
//Set the billing address post code of an account
$accountBean->billing_address_postalcode = '12345';
//Save both changes.
$accountBean->save();
//Create a new case (see the BeanFactory section)
$caseBean = BeanFactory::newBean('Cases');
//Give it a name and save
$caseBean->name = 'New Case name';
$caseBean->save();
Whether to
save or update a bean is decided by checking the id
field of the bean.
If id
is set then SuiteCRM will attempt to perform an update. If there
is no id
then one will be generated and a new record will be inserted
into the database. If for some reason you have supplied an id
but the
record is new (perhaps in a custom import script) then you can set
new_with_id
to true on the bean to let SuiteCRM know that this record
is new.
Use the mark_deleted
method for this. It will set the deleted
field to 1
, also mark any relationships of that Bean
as deleted, and remove the reference to that item from the Recently viewed lists.
$bean->mark_deleted($id);
// Saving is required afterwards
$bean->save();
This method will also call the appropriate before_delete
and after_delete
logic hooks.
We have seen how to save single records but, in a CRM system, relationships between records are as important as the records themselves. For example an account may have a list of cases associated with it, a contact will have an account that it falls under etc. We can get and set relationships between beans using several methods.
The get_linked_beans
method allows retrieving a list of related beans
for a given record.
get_linked_beans(
$field_name,
$bean_name = '',
$order_by = '',
$begin_index = 0,
$end_index = -1,
$deleted = 0,
$optional_where = "");
$field_name
The link field name for this link. Note that this is not the same as
the name of the relationship. If you are unsure of what this should be
you can take a look into the cached vardefs of a module in
cache/modules/<TheModule>/<TheModule>Vardefs.php
for the link
definition.
$bean_name
Used to specify the bean name of the beans you are expecting back. Not needed in current versions, kept for backward compatibility or for the unlikely event you have an old style relationship.
$order_by
Optionally, add a clause like last_name DESC
to get sorted results (only available from SuiteCRM 7.4 onwards).
$begin_index
Skips the initial $begin_index
results. Can be used to paginate.
$end_index
Return up to the $end_index
result. Can be used to paginate.
$deleted
Controls whether deleted or non deleted records are shown. If true only deleted records will be returned. If false only non deleted records will be returned.
$optional_where
Allows filtering the results using an SQL WHERE clause. See the
get_list
method for more details.
get_linked_beans
returns an array of the linked beans.
$accountBean->get_linked_beans(
'contacts',
'Contacts',
array(),
0,
10,
0,
"contacts.primary_address_country = 'USA'");
In addition to the get_linked_beans
call you can also load and access
the relationships more directly.
Before accessing a relationship you must use the load_relationship
call to ensure it is available. This call takes the link name of the
relationship (not the name of the relationship). As mentioned previously
you can find the name of the link in
cache/modules/<TheModule>/<TheModule>Vardefs.php
if you’re not sure.
//Load the relationship
$accountBean->load_relationship('contacts');
//Can now call methods on the relationship object:
$contactIds = $accountBean->contacts->get();
get
Returns the ids of the related records in this relationship e.g for the account - contacts relationship in the example above it will return the list of ids for contacts associated with the account.
getBeans
Similar to get
but returns an array of beans instead of just ids.
getBeans
will
load the full bean for each related record. This may cause poor
performance for relationships with a large number of beans.
add
Allows relating records to the current bean. add
takes a single id or
bean or an array of ids or beans. If the bean is available this should
be used since it prevents reloading the bean. For example to add a
contact to the relationship in our example we can do the following:
//Load the relationship
$accountBean->load_relationship('contacts');
//Create a new demo contact
$contactBean = BeanFactory::newBean('Contacts');
$contactBean->first_name = 'Jim';
$contactBean->last_name = 'Mackin';
$contactBean->save();
//Link the bean to $accountBean
$accountBean->contacts->add($contactBean);
delete
delete
allows unrelating beans. Counter-intuitively it accepts the ids
of both the bean and the related bean. For the related bean you should
pass the bean if it is available e.g when unrelating an account and
contact:
//Load the relationship
$accountBean->load_relationship('contacts');
//Unlink the contact from the account - assumes $contactBean is a Contact SugarBean
$accountBean->contacts->delete($accountBean->id, $contactBean);
Be careful with the delete method. Omitting the second argument will cause all relationships for this bean to be removed.
Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.