K4:KDBItem class
From In-Portal Developers Guide
m (категория) |
Current revision (18:37, 26 November 2010) (view source) (Lang. side-box) |
||
(7 intermediate revisions not shown.) | |||
Line 1: | Line 1: | ||
{{toc | category = Системные классы | sortkey = 003.001}} | {{toc | category = Системные классы | sortkey = 003.001}} | ||
<!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! --> | <!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! --> | ||
- | + | The '''<code>kDBItem</code>''' class is one of the base classes. It provides methods for working with data. Events are widely used to connect between objects of the '''<code>kDBItem</code>''' and other parts of the system. Events occurring during the execution of methods of the '''<code>kDBItem</code>''' class can be [[K4:Hooks|hooked]] to execute needed actions. The other way around is also possible - the system has events whose execution triggers execution of methods of the '''<code>kDBItem</code>''' class. | |
- | == | + | == Loading from the Database == |
- | + | The method '''<code>Load</code>''' is used to load data from the database. The method returns '''<code>true</code>''' if data was loaded successfully and '''<code>false</code>''' otherwise. If there is a need to check whether a single object was successfully loaded from the database, then the method '''<code>isLoaded</code>''' can be used, which returns the status (<code>true or false</code>) of loading the last object. Requirements for loading data are defined as the parameters of the method and can be simple or complex. | |
- | + | A simple requirement would be where the first parameter is the value of one of the fields of a record. Usually it's an '''<code>Integer</code>''' value of the primary key, in which case a second parameter isn't needed. If the value of a different field is passed in the first parameter, then the second parameter must be the name of the corresponding field. | |
<source lang="php"> | <source lang="php"> | ||
- | // | + | // Obtain a reference to the object. The third parameter prevents the automatic load of data to the object |
$user =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); | $user =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); | ||
/* @var $user kDBItem */ | /* @var $user kDBItem */ | ||
- | // | + | // Load the data of the object with ID = 23 |
$user->Load(23); | $user->Load(23); | ||
- | // | + | // Here there may be actions with the object |
- | // | + | // Load user data to the object by his e-mail address |
$user->Load('erik@intechnic.com', 'Email'); | $user->Load('erik@intechnic.com', 'Email'); | ||
</source> | </source> | ||
- | + | A complex requirement for loading data from the database can be where the first parameter passes an array containing the field names as keys and, as values, the values that should be in the corresponding fields of the loaded record. | |
<source lang="php"> | <source lang="php"> | ||
Line 33: | Line 33: | ||
</source> | </source> | ||
- | + | As a result, to load this data, an SQL-query will be used with the following conditions: | |
<source lang="sql"> | <source lang="sql"> | ||
Line 39: | Line 39: | ||
</source> | </source> | ||
- | == | + | == Changing Data == |
- | + | '''<code>SetField</code>''' and '''<code>SetDBField</code>''' are used to change the value of a field. '''<code>SetDBField</code>''' enters the value of the '''<code>$value</code>''' variable into the field exactly as it's passed. '''<code>SetField</code>''' before entering the record checks whether a formatter is assigned for the field, and if one is assigned, transforms the value of the field using the [[K4:Formatters|formatter's]] Parse method. | |
<source lang="php"> | <source lang="php"> | ||
- | // | + | // For example, with formatting a date |
$user->SetField('dob', '12/22/1971'); | $user->SetField('dob', '12/22/1971'); | ||
- | // | + | // The result will be the same as |
$user->SetDBField('dob', 62197200); | $user->SetDBField('dob', 62197200); | ||
</source> | </source> | ||
- | + | Often, it's convenient to change the data for several fields at once. For example, to overwrite the value of several fields, that were received as a result of a form submission. For that we have the '''<code>SetFieldsFromHash</code>''' and '''<code>SetDBFieldsFromHash</code>''' functions. They accept an array as a parameter, that contains the names of the fields and the values for them. '''<code>SetFieldsFromHash</code>''', just like the above '''<code>SetField</code>''', calls the [[K4:Formatters|formatter's]] '''<code>Parse</code>''' method to transform a value. | |
<source lang="php"> | <source lang="php"> | ||
Line 58: | Line 58: | ||
'dob' => '12/22/1971' | 'dob' => '12/22/1971' | ||
); | ); | ||
- | // | + | // Usually, an array like this is received from a request constructed like this |
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | ||
list ($id, $field_values) = each($items_info); | list ($id, $field_values) = each($items_info); | ||
- | // | + | // and, finally,to record the values into the object |
$user->SetFieldsFromHash($field_values); | $user->SetFieldsFromHash($field_values); | ||
</source> | </source> | ||
- | + | Sometimes, for example when importing data, we have to reuse the same object of the '''<code>kDBItem</code>''' class with different sets of data. The '''<code>Clear</code>''' method can be useful in such cases, which sets default values for all fields, thus guaranteeing that each data set will contain only its own data. | |
- | == | + | == Discovering Changed Fields == |
- | + | Often, when changing an object's data, it's useful to check which fields were changed and which weren't. For example, if some actions only need to be performed if certain fields were changed. It's possible to get the value of a field before it was changed, right after loading the data from the database, with the help of the '''<code>GetOriginalField</code>''' method. | |
- | == | + | == Validation == |
- | + | The '''<code>Validate</code>''' method is used to check an object's data. If, during the execution of the method, a discrepancy between data and requirements for the data is found, the object's '''<code>FieldErrors</code>''' property will contain an array, with the names of the fields used as key top-level elements, appended to second-level elements with the '''<code>'pseudo'</code>''' keys. These are error codes that summarize the nature of the problem. It's possible to check whether a method has such error codes with the '''<code>HasErrors</code>''' method. | |
- | + | Error codes can be found in the [[K4:Debugger|debugger]] by opening it after an unsuccessful attempt to save data. | |
<source lang="php"> | <source lang="php"> | ||
[Name] = Array | [Name] = Array | ||
Line 82: | Line 82: | ||
</source> | </source> | ||
- | + | Sometimes it's necessary to not only make note of error information concerning fields, but to record it. For example, when writing functions that validate data that are specific to a particular programming problem. In that case, to represent an error in a field, the '''<code>kDBItem</code>''' class provides the '''<code>SetError</code>''' method. | |
- | + | For example, when editing data in a form, it's possible to choose a category from a list to which the object belongs. However, before saving to the database, it's a good idea to make sure that a category with such an ID really exists: | |
<source lang="php"> | <source lang="php"> | ||
Line 98: | Line 98: | ||
$category_id = $object->getDBField('CategoryId'); | $category_id = $object->getDBField('CategoryId'); | ||
if (!$category_id) { | if (!$category_id) { | ||
- | // | + | // value not passed - validation not needed |
return; | return; | ||
} | } | ||
if ($category_id == $object->GetOriginalField('CategoryId')) { | if ($category_id == $object->GetOriginalField('CategoryId')) { | ||
- | // | + | // value did not change - validation not needed |
return; | return; | ||
} | } | ||
Line 116: | Line 116: | ||
</source> | </source> | ||
- | == | + | == Saving to the Database == |
- | + | The methods '''<code>Create</code>''' and '''<code>Update</code>''' are used to save to the database. The '''<code>Create</code>''' method is for creating a new record. The '''<code>Update</code>''' method - for changing an existing record. By default, both of these methods, before saving data to the database, perform a valdiation using the '''<code>Validate</code>''' method, and make a record only if validation is successful. In the below example, a data import is being done and if the data of the user being created don't validate, then a record simply won't be created. | |
<source lang="php"> | <source lang="php"> | ||
- | // | + | // Place data from an outside source into an array |
$sql = 'SELECT username, password, email | $sql = 'SELECT username, password, email | ||
FROM user'; | FROM user'; | ||
$users = $application->Conn->Query($sql); | $users = $application->Conn->Query($sql); | ||
- | // | + | // Create an object of the kDBItem class |
$user =& $application->recallObject('u.-item', null, Array('skip-autoload' => true)); | $user =& $application->recallObject('u.-item', null, Array('skip-autoload' => true)); | ||
/* @var $user kDBItem*/ | /* @var $user kDBItem*/ | ||
foreach ($users AS $user_data) { | foreach ($users AS $user_data) { | ||
- | // | + | // Set default values by calling the Clear method |
$user->Clear(); | $user->Clear(); | ||
- | // | + | // Set field values for the record being imported |
$user->SetDBField('Login', $user_data['username']); | $user->SetDBField('Login', $user_data['username']); | ||
$user->SetDBField('Email', $user_data['email']); | $user->SetDBField('Email', $user_data['email']); | ||
Line 139: | Line 139: | ||
$user->SetDBField('VerifyPassword', $user_data['password']); | $user->SetDBField('VerifyPassword', $user_data['password']); | ||
- | // | + | // Call the Create method to create the record in our system |
$user->Create(); | $user->Create(); | ||
} | } | ||
</source> | </source> | ||
- | == | + | == Using Events == |
- | + | The four main methods of the '''<code>kDBItem</code>''' class that can directly connect to the database are: | |
* '''<code>Create</code>'''; | * '''<code>Create</code>'''; | ||
* '''<code>Load</code>'''; | * '''<code>Load</code>'''; | ||
* '''<code>Update</code>'''; | * '''<code>Update</code>'''; | ||
* '''<code>Delete</code>'''. | * '''<code>Delete</code>'''. | ||
- | + | Each of these methods in certain situations calls events that can be used to connect an object of the '''<code>kDBItem</code>''' class with the rest of the system. All four of these methods can, while executing, call the events '''<code>OnBeforeItem****</code>''' and '''<code>OnAfterItem****</code>''', where '''<code>****</code>''' is the name of the method. The '''<code>OnBeforeItem****</code>''' event gets called before making the change in the database. The '''<code>OnAfterItem****</code>''' event is called only after successfully performing the action in the database. | |
- | + | The '''<code>Create</code>''' and '''<code>Update</code>''' methods can also call the '''<code>OnAfterItemValidate</code>''' event. This happens in the case where a validation of the object's data was performed and the validation was successful. The '''<code>OnAfterItemValidate</code>''' is called before a query is made to the database. Below is an example of how the <code>OnAfterItemDelete</code> event can be used to perform additional actions after successfully deleting a record. | |
<source lang="php"> | <source lang="php"> | ||
Line 160: | Line 160: | ||
/* @var $object kDBItem */ | /* @var $object kDBItem */ | ||
- | // | + | // Despite the record in the database already being deleted, all its data is kept in memory and |
- | // | + | // depending on the value of the fields of the deleted record, it's possible to execute various actions |
$topic_id = $object->GetDBField('TopicId'); | $topic_id = $object->GetDBField('TopicId'); | ||
if (!$topic_id) { | if (!$topic_id) { | ||
Line 176: | Line 176: | ||
</source> | </source> | ||
- | == | + | == Key Events That Use kDBItem Class == |
- | + | The key events that use the '''<code>kDBItem</code>''' class are located in the '''<code>kDBEventHandler</code>''' class. | |
{| class="prettytable" | {| class="prettytable" | ||
- | ! | + | ! Key Events || Similar Events, Used When Working with Temporary Tables || kDBItem Methods Used |
|- | |- | ||
| <code>OnNew</code> || <code>OnPreCreate</code> || <code>setID(0)</code> | | <code>OnNew</code> || <code>OnPreCreate</code> || <code>setID(0)</code> | ||
Line 189: | Line 189: | ||
|} | |} | ||
- | + | These events, as a rule, are initialized from the web page, i.e. their names are passed in a request to the server. | |
- | + | * The '''<code>OnNew</code>''' event occurs when a form for entering new data to create a new record is opened. | |
- | * '''<code>OnCreate</code>''' - | + | * '''<code>OnCreate</code>''' - when sending data to the server to create a new record. |
- | * '''<code>OnUpdate</code>''' - | + | * '''<code>OnUpdate</code>''' - when sending data to the server to change existing record. |
<source lang="php"> | <source lang="php"> | ||
function OnUpdate(&$event) | function OnUpdate(&$event) | ||
{ | { | ||
- | // | + | // Get a reference to an object of the kDBItem class. |
$object =& $event->getObject( Array('skip_autoload' => true) ); | $object =& $event->getObject( Array('skip_autoload' => true) ); | ||
- | // | + | // Get data from the request. |
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); | ||
if ($items_info) { | if ($items_info) { | ||
foreach ($items_info as $id => $field_values) { | foreach ($items_info as $id => $field_values) { | ||
- | // | + | // Load data from the database by its ID |
$object->Load($id); | $object->Load($id); | ||
- | // | + | // Insert data from the request into the object. |
$object->SetFieldsFromHash($field_values); | $object->SetFieldsFromHash($field_values); | ||
$this->customProcessing($event, 'before'); | $this->customProcessing($event, 'before'); | ||
- | // | + | // Call method from the kDBItem class. |
if ( $object->Update($id) ) { | if ( $object->Update($id) ) { | ||
$this->customProcessing($event, 'after'); | $this->customProcessing($event, 'after'); | ||
Line 229: | Line 229: | ||
</source> | </source> | ||
- | == | + | == See Also == |
* [[K4:Debugger|Debugger]] | * [[K4:Debugger|Debugger]] | ||
* [[K4:Formatters|Formatters]] | * [[K4:Formatters|Formatters]] | ||
* [[K4:Hooks|Hooks]] | * [[K4:Hooks|Hooks]] | ||
+ | |||
+ | |||
+ | [[en:{{FULLPAGENAME}}]] | ||
+ | [[ru:K4:Работа_с_классом_kDBItem]] |
Current revision
| ||
---|---|---|
Статьи в этой категории | ||
|
The kDBItem
class is one of the base classes. It provides methods for working with data. Events are widely used to connect between objects of the kDBItem
and other parts of the system. Events occurring during the execution of methods of the kDBItem
class can be hooked to execute needed actions. The other way around is also possible - the system has events whose execution triggers execution of methods of the kDBItem
class.
Contents |
Loading from the Database
The method Load
is used to load data from the database. The method returns true
if data was loaded successfully and false
otherwise. If there is a need to check whether a single object was successfully loaded from the database, then the method isLoaded
can be used, which returns the status (true or false
) of loading the last object. Requirements for loading data are defined as the parameters of the method and can be simple or complex.
A simple requirement would be where the first parameter is the value of one of the fields of a record. Usually it's an Integer
value of the primary key, in which case a second parameter isn't needed. If the value of a different field is passed in the first parameter, then the second parameter must be the name of the corresponding field.
// Obtain a reference to the object. The third parameter prevents the automatic load of data to the object $user =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); /* @var $user kDBItem */ // Load the data of the object with ID = 23 $user->Load(23); // Here there may be actions with the object // Load user data to the object by his e-mail address $user->Load('erik@intechnic.com', 'Email');
A complex requirement for loading data from the database can be where the first parameter passes an array containing the field names as keys and, as values, the values that should be in the corresponding fields of the loaded record.
$load_keys = Array( 'FirstName' => 'Erik', 'LastName' => 'Snarski' ); $user->Load($load_keys);
As a result, to load this data, an SQL-query will be used with the following conditions:
WHERE FirstName = 'Erik' AND LastName = 'Snarski'
Changing Data
SetField
and SetDBField
are used to change the value of a field. SetDBField
enters the value of the $value
variable into the field exactly as it's passed. SetField
before entering the record checks whether a formatter is assigned for the field, and if one is assigned, transforms the value of the field using the formatter's Parse method.
// For example, with formatting a date $user->SetField('dob', '12/22/1971'); // The result will be the same as $user->SetDBField('dob', 62197200);
Often, it's convenient to change the data for several fields at once. For example, to overwrite the value of several fields, that were received as a result of a form submission. For that we have the SetFieldsFromHash
and SetDBFieldsFromHash
functions. They accept an array as a parameter, that contains the names of the fields and the values for them. SetFieldsFromHash
, just like the above SetField
, calls the formatter's Parse
method to transform a value.
$field_values = Array( 'Email' => 'erik@intechnic.com', 'FirstName' => 'Erik', 'LastName' => 'Snarski', 'dob' => '12/22/1971' ); // Usually, an array like this is received from a request constructed like this $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); list ($id, $field_values) = each($items_info); // and, finally,to record the values into the object $user->SetFieldsFromHash($field_values);
Sometimes, for example when importing data, we have to reuse the same object of the kDBItem
class with different sets of data. The Clear
method can be useful in such cases, which sets default values for all fields, thus guaranteeing that each data set will contain only its own data.
Discovering Changed Fields
Often, when changing an object's data, it's useful to check which fields were changed and which weren't. For example, if some actions only need to be performed if certain fields were changed. It's possible to get the value of a field before it was changed, right after loading the data from the database, with the help of the GetOriginalField
method.
Validation
The Validate
method is used to check an object's data. If, during the execution of the method, a discrepancy between data and requirements for the data is found, the object's FieldErrors
property will contain an array, with the names of the fields used as key top-level elements, appended to second-level elements with the 'pseudo'
keys. These are error codes that summarize the nature of the problem. It's possible to check whether a method has such error codes with the HasErrors
method.
Error codes can be found in the debugger by opening it after an unsuccessful attempt to save data.
[Name] = Array ( [pseudo] = required )
Sometimes it's necessary to not only make note of error information concerning fields, but to record it. For example, when writing functions that validate data that are specific to a particular programming problem. In that case, to represent an error in a field, the kDBItem
class provides the SetError
method.
For example, when editing data in a form, it's possible to choose a category from a list to which the object belongs. However, before saving to the database, it's a good idea to make sure that a category with such an ID really exists:
/** * * @param kEvent $event */ function OnBeforeItemUpdate(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $category_id = $object->getDBField('CategoryId'); if (!$category_id) { // value not passed - validation not needed return; } if ($category_id == $object->GetOriginalField('CategoryId')) { // value did not change - validation not needed return; } $sql = 'SELECT COUNT(*) FROM ' . $this->Application->getUnitOption('c', 'TableName') . ' WHERE ' . $this->Application->getUnitOption('c', 'IDField') . ' = ' . $this->Conn->qstr($category_id); if (!$this->Conn->GetOne($sql)) { $object->SetError('CategoryId', 'invalid_category', 'la_error_InvalidCategory'); } }
Saving to the Database
The methods Create
and Update
are used to save to the database. The Create
method is for creating a new record. The Update
method - for changing an existing record. By default, both of these methods, before saving data to the database, perform a valdiation using the Validate
method, and make a record only if validation is successful. In the below example, a data import is being done and if the data of the user being created don't validate, then a record simply won't be created.
// Place data from an outside source into an array $sql = 'SELECT username, password, email FROM user'; $users = $application->Conn->Query($sql); // Create an object of the kDBItem class $user =& $application->recallObject('u.-item', null, Array('skip-autoload' => true)); /* @var $user kDBItem*/ foreach ($users AS $user_data) { // Set default values by calling the Clear method $user->Clear(); // Set field values for the record being imported $user->SetDBField('Login', $user_data['username']); $user->SetDBField('Email', $user_data['email']); $user->SetDBField('Password', $user_data['password']); $user->SetDBField('VerifyPassword', $user_data['password']); // Call the Create method to create the record in our system $user->Create(); }
Using Events
The four main methods of the kDBItem
class that can directly connect to the database are:
-
Create
; -
Load
; -
Update
; -
Delete
.
Each of these methods in certain situations calls events that can be used to connect an object of the kDBItem
class with the rest of the system. All four of these methods can, while executing, call the events OnBeforeItem****
and OnAfterItem****
, where ****
is the name of the method. The OnBeforeItem****
event gets called before making the change in the database. The OnAfterItem****
event is called only after successfully performing the action in the database.
The Create
and Update
methods can also call the OnAfterItemValidate
event. This happens in the case where a validation of the object's data was performed and the validation was successful. The OnAfterItemValidate
is called before a query is made to the database. Below is an example of how the OnAfterItemDelete
event can be used to perform additional actions after successfully deleting a record.
function OnAfterItemDelete(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ // Despite the record in the database already being deleted, all its data is kept in memory and // depending on the value of the fields of the deleted record, it's possible to execute various actions $topic_id = $object->GetDBField('TopicId'); if (!$topic_id) { // deleting non-existing post return ; } $post_helper =& $this->Application->recallObject('PostHelper'); /* @var $post_helper PostHelper */ // update posts count in topic $post_helper->updatePostCount($topic_id, -1); }
Key Events That Use kDBItem Class
The key events that use the kDBItem
class are located in the kDBEventHandler
class.
Key Events | Similar Events, Used When Working with Temporary Tables | kDBItem Methods Used |
---|---|---|
OnNew | OnPreCreate | setID(0)
|
OnCreate | OnPreSaveCreated | SetFieldsFromHash , Create , IsTempTable , setTempID , setID
|
OnUpdate | OnPreSave | Load , SetFieldsFromHash , Update , Load
|
These events, as a rule, are initialized from the web page, i.e. their names are passed in a request to the server.
- The
OnNew
event occurs when a form for entering new data to create a new record is opened. -
OnCreate
- when sending data to the server to create a new record. -
OnUpdate
- when sending data to the server to change existing record.
function OnUpdate(&$event) { // Get a reference to an object of the kDBItem class. $object =& $event->getObject( Array('skip_autoload' => true) ); // Get data from the request. $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); if ($items_info) { foreach ($items_info as $id => $field_values) { // Load data from the database by its ID $object->Load($id); // Insert data from the request into the object. $object->SetFieldsFromHash($field_values); $this->customProcessing($event, 'before'); // Call method from the kDBItem class. if ( $object->Update($id) ) { $this->customProcessing($event, 'after'); $event->status=erSUCCESS; } else { $event->status=erFAIL; $event->redirect=false; break; } } } $event->setRedirectParam('opener', 'u'); }