https://wiki.fogproject.org/wiki/index.php?title=FOGController&feed=atom&action=history
FOGController - Revision history
2024-03-29T01:44:22Z
Revision history for this page on the wiki
MediaWiki 1.30.0
https://wiki.fogproject.org/wiki/index.php?title=FOGController&diff=4188&oldid=prev
Chad-bisd: /* Overview */ added Category:Development
2011-09-30T16:49:09Z
<p><span dir="auto"><span class="autocomment">Overview: </span> added Category:Development</span></p>
<p><b>New page</b></p><div>== Overview ==<br />
FOGController is a new Chainable PHP Class developed for use in FOG web applications.<br />
This Class acts as an abstraction layer between PHP's data and its database entry.<br />
<br />
The Class is an abstract Class, providing a base for FOG Classes to build from.<br />
All you need to do is describe to the Class the relationship between your Database fields and common names used when accessing the data.<br />
<br />
* Please note all of this is developmental and could change at any moment<br />
[[Category:Development]]<br />
<br />
== Variables & Methods ==<br />
'''Variables and their defaults'''<br />
<pre><br />
abstract class FOGController<br />
{<br />
// Table<br />
protected $databaseTable = '';<br />
<br />
// Name -> Database field name<br />
protected $databaseFields = array();<br />
<br />
// Do not update these database fields<br />
protected $databaseFieldsToIgnore = array(<br />
'createdBy',<br />
'createdTime'<br />
);<br />
<br />
// Allow setting / getting of these additional fields<br />
protected $additionalFields = array();<br />
<br />
// Required database fields<br />
protected $databaseFieldsRequired = array(<br />
'id',<br />
'name'<br />
);<br />
<br />
// Store data array<br />
protected $data = array();<br />
<br />
// Auto save class data on __destruct<br />
protected $autoSave = false;<br />
<br />
// DEBUG mode - print all Errors & SQL queries<br />
protected $debug = false;<br />
}<br />
</pre><br />
<br />
<br />
'''Methods'''<br />
<pre><br />
$this public function __construct($data)<br />
$this public function __destruct()<br />
$this public function set($key, $value)<br />
$this public function get($key)<br />
$this public function add($key, $value)<br />
$this public function remove($key, $object)<br />
boolean public function save()<br />
boolean public function load($field = 'id')<br />
boolean public function destroy($field = 'id')<br />
void public function error($txt, $data = array())<br />
void public function info($txt, $data = array())<br />
boolean public function isValid()<br />
boolean private function isTableDefined()<br />
string public function __toString()<br />
</pre><br />
<br />
== Example ==<br />
This is an example of FOG's up coming OS Class in v0.33<br />
<br />
'''OS.class.php'''<br />
<pre><br />
class OS extends FOGController<br />
{<br />
// Table<br />
protected $databaseTable = 'os';<br />
<br />
// Name -> Database field name<br />
protected $databaseFields = array(<br />
'id' => 'osID',<br />
'name' => 'osName',<br />
'description' => 'osDescription'<br />
);<br />
}<br />
</pre><br />
<br />
Only $databaseFields is required.<br />
<br />
Providing $databaseTable gives access to FOGControllers save() and load() functions.<br />
<br />
'''Example: Add new OS'''<br />
<pre><br />
// New OS Object<br />
$OS = new OS();<br />
<br />
// Set name -> Set description -> Save to database (returns true on success)<br />
if ($OS->set('name', 'Windows 8')->set('description', 'more junk')->save())<br />
{<br />
// id property is added after a successful save<br />
$FOGCore->setMessage(sprintf('OS Added: ID: %s, Name: %s', $OS->get('id'), $OS->get('name')));<br />
}<br />
else<br />
{<br />
$FOGCore->setMessage(sprintf('Failed to add: %s', $OS->get('name')));<br />
}<br />
<br />
// Redirect back to self<br />
$FOGCore->redirect();<br />
</pre><br />
<br />
'''Example: Update an Existing OS'''<br />
<pre><br />
// OS ID Variable<br />
$id = '1';<br />
// Load OS - auto loads from database when ID is passed<br />
$OS = new OS($id);<br />
<br />
// Is OS valid? (was it loaded from the database correctly)<br />
if ($OS->isValid())<br />
{<br />
print_r($OS);<br />
}<br />
</pre><br />
<br />
== Class ==<br />
'''FOGController.class.php'''<br />
<pre><br />
<?php<br />
<br />
// Blackout - 1:28 PM 23/09/2011<br />
abstract class FOGController<br />
{<br />
// Table<br />
protected $databaseTable = '';<br />
<br />
// Name -> Database field name<br />
protected $databaseFields = array();<br />
<br />
// Do not update these database fields<br />
protected $databaseFieldsToIgnore = array(<br />
'createdBy',<br />
'createdTime'<br />
);<br />
<br />
// Allow setting / getting of these additional fields<br />
protected $additionalFields = array();<br />
<br />
// Required database fields<br />
protected $databaseFieldsRequired = array(<br />
'id',<br />
'name'<br />
);<br />
<br />
// Store data array<br />
protected $data = array();<br />
<br />
// Auto save class data on __destruct<br />
protected $autoSave = false;<br />
<br />
// DEBUG mode - print all Errors & SQL queries<br />
protected $debug = true; <br />
<br />
// Database Class<br />
protected $db;<br />
<br />
// Construct<br />
public function __construct($data)<br />
{<br />
try<br />
{<br />
// Error checking<br />
if (!count($this->databaseFields))<br />
{<br />
throw new Exception('No database fields defined for this class!');<br />
}<br />
<br />
// Database<br />
$this->db = $GLOBALS['db'];<br />
<br />
// Add incoming data<br />
if (is_array($data))<br />
{<br />
// Iterate data -> Set data<br />
foreach ($data AS $key => $value)<br />
{<br />
$this->set($key, $value);<br />
}<br />
}<br />
// If incoming data is an INT -> Set as ID -> Load from database<br />
elseif (is_numeric($data))<br />
{<br />
if ($data <= 0)<br />
{<br />
throw new Exception(sprintf('ID less than or equal to 0: Data: %s', $data));<br />
//return false;<br />
}<br />
<br />
$this->set('id', $data)->load();<br />
}<br />
// Unknown data format<br />
else<br />
{<br />
throw new Exception('No data array or ID passed!');<br />
}<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Create Class Failed: Class: %s, Error: %s', array(get_class($this), $e->getMessage()));<br />
}<br />
<br />
return $this;<br />
}<br />
<br />
// Destruct<br />
public function __destruct()<br />
{<br />
// Auto save<br />
if ($this->autoSave)<br />
{<br />
$this->save();<br />
}<br />
}<br />
<br />
// Set<br />
public function set($key, $value)<br />
{<br />
try<br />
{<br />
$databaseFieldsRev = array_flip($this->databaseFields);<br />
<br />
if (!array_key_exists($key, $this->databaseFields) && !in_array($key, $this->additionalFields) && !array_key_exists($key, $databaseFieldsRev))<br />
{<br />
throw new Exception('Invalid data being set');<br />
}<br />
<br />
if (array_key_exists($key, $databaseFieldsRev))<br />
{<br />
$key = $databaseFieldsRev[$key];<br />
}<br />
<br />
$this->data[$key] = $value;<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Set Failed: Class: %s, Key: %s, Value: %s, Error: %s', array(get_class($this), $key, $value, $e->getMessage()));<br />
}<br />
<br />
return $this;<br />
}<br />
<br />
// Get<br />
public function get($key)<br />
{<br />
return (isset($this->data[$key]) ? $this->data[$key] : '');<br />
}<br />
<br />
/*<br />
public function __set($key, $value)<br />
{<br />
return $this->set($key, $value);<br />
}<br />
<br />
public function __get($key)<br />
{<br />
return $this->get($key);<br />
}<br />
*/<br />
<br />
// Add<br />
public function add($key, $value)<br />
{<br />
try<br />
{<br />
$databaseFieldsRev = array_flip($this->databaseFields);<br />
<br />
if (!array_key_exists($key, $this->databaseFields) && !in_array($key, $this->additionalFields) && !array_key_exists($key, $databaseFieldsRev))<br />
{<br />
throw new Exception('Invalid data being set');<br />
}<br />
<br />
if (array_key_exists($key, $databaseFieldsRev))<br />
{<br />
$key = $databaseFieldsRev[$key];<br />
}<br />
<br />
$this->data[$key][] = $value;<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Add Failed: Class: %s, Key: %s, Value: %s, Error: %s', array(get_class($this), $key, $value, $e->getMessage()));<br />
}<br />
<br />
return $this;<br />
}<br />
<br />
// Remove<br />
public function remove($key, $object)<br />
{<br />
try<br />
{<br />
$databaseFieldsRev = array_flip($this->databaseFields);<br />
<br />
if (!array_key_exists($key, $this->databaseFields) && !in_array($key, $this->additionalFields) && !array_key_exists($key, $databaseFieldsRev))<br />
{<br />
throw new Exception('Invalid data being set');<br />
}<br />
<br />
if (array_key_exists($key, $databaseFieldsRev))<br />
{<br />
$key = $databaseFieldsRev[$key];<br />
}<br />
<br />
foreach ((array)$this->data[$key] AS $i => $data)<br />
{<br />
if ($data->get('id') != $object->get('id'))<br />
{<br />
$newDataArray[] = $data;<br />
}<br />
}<br />
<br />
$this->data[$key] = (array)$newDataArray;<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Remove Failed: Class: %s, Key: %s, Object: %s, Error: %s', array(get_class($this), $key, $object, $e->getMessage()));<br />
}<br />
<br />
return $this;<br />
}<br />
<br />
// Save<br />
public function save()<br />
{<br />
try<br />
{<br />
// Error checking<br />
if (!$this->isTableDefined())<br />
{<br />
throw new Exception('No Table defined for this class');<br />
}<br />
<br />
// Variables<br />
$fieldData = array();<br />
$fieldsToUpdate = $this->databaseFields;<br />
$fieldToName = array_flip($this->databaseFields);<br />
<br />
// Remove unwanted fields for update query<br />
foreach ($this->databaseFields AS $name => $fieldName)<br />
{<br />
if (in_array($name, $this->databaseFieldsToIgnore))<br />
{<br />
unset($fieldsToUpdate[$name]);<br />
}<br />
}<br />
<br />
// Build insert key and value arrays<br />
foreach ($this->databaseFields AS $name => $fieldName)<br />
{<br />
$insertKeys[] = $this->db->sanitize($fieldName);<br />
$insertValues[] = $this->db->sanitize($this->get($name));<br />
}<br />
<br />
// Build update field array using filtered data<br />
foreach ($fieldsToUpdate AS $name => $fieldName)<br />
{<br />
$updateData[] = sprintf("`%s`='%s'", $this->db->sanitize($fieldName), $this->db->sanitize($this->get($name)));<br />
}<br />
<br />
// Insert & Update query all-in-one<br />
$query = sprintf("INSERT INTO `%s` (`%s`) VALUES ('%s') ON DUPLICATE KEY UPDATE %s",<br />
$this->db->sanitize($this->databaseTable),<br />
implode("`, `", $insertKeys),<br />
implode("', '", $insertValues),<br />
implode(', ', $updateData)<br />
);<br />
<br />
// INFO<br />
$this->info($query);<br />
<br />
if (!$this->db->query($query))<br />
{<br />
// Query failed<br />
throw new Exception($this->db->error());<br />
}<br />
<br />
// Database query was successful - set ID if ID was not set<br />
if (!$this->get('id'))<br />
{<br />
$this->set('id', $this->db->insert_id());<br />
}<br />
<br />
// Success<br />
return true;<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Database Save Failed: Class: %s, ID: %s, Error: %s', array(get_class($this), $this->get('id'), $e->getMessage()));<br />
}<br />
<br />
// Fail<br />
return false;<br />
}<br />
<br />
// Load<br />
public function load($field = 'id')<br />
{<br />
try<br />
{<br />
// Error checking<br />
if (!$this->isTableDefined())<br />
{<br />
throw new Exception('No Table defined for this class');<br />
}<br />
if (!$this->get($field))<br />
{<br />
throw new Exception(sprintf('Operation field not set: %s', strtoupper($field)));<br />
}<br />
<br />
// Variables<br />
$fieldToName = array_flip($this->databaseFields);<br />
<br />
// Build query<br />
if (is_array($this->get($field)))<br />
{<br />
// Multiple values<br />
foreach ($this->get($field) AS $fieldValue)<br />
{<br />
$fieldData[] = sprintf("`%s`='%s'", $this->db->sanitize($this->databaseFields[$field]), $this->db->sanitize($fieldValue));<br />
}<br />
<br />
$query = sprintf("SELECT * FROM `%s` WHERE %s",<br />
$this->db->sanitize($this->databaseTable),<br />
implode(' OR ', $fieldData)<br />
);<br />
}<br />
else<br />
{<br />
// Single value<br />
$query = sprintf("SELECT * FROM `%s` WHERE `%s`='%s'",<br />
$this->db->sanitize($this->databaseTable),<br />
$this->db->sanitize($this->databaseFields[$field]),<br />
$this->db->sanitize($this->get($field))<br />
);<br />
}<br />
<br />
// INFO<br />
$this->info($query);<br />
<br />
// Did we find a row in the database?<br />
if (!$queryData = $this->db->query($query)->fetch()->get())<br />
{<br />
throw new Exception($this->db->error());<br />
}<br />
<br />
// Loop returned rows -> Set new data<br />
foreach ($queryData AS $key => $value)<br />
{<br />
$this->set($fieldToName[$key], (string)$value);<br />
}<br />
<br />
// Success<br />
return true;<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Database Load Failed: Class: %s, ID: %s, Error: %s', array(get_class($this), $this->get('id'), $e->getMessage()));<br />
}<br />
<br />
// Fail<br />
return false;<br />
}<br />
<br />
// Destroy<br />
public function destroy($field = 'id')<br />
{<br />
try<br />
{<br />
// Error checking<br />
if (!$this->isTableDefined())<br />
{<br />
throw new Exception('No Table defined for this class');<br />
}<br />
if (!$this->get($field))<br />
{<br />
throw new Exception(sprintf('Operation field not set: %s', strtoupper($field)));<br />
}<br />
<br />
// Variables<br />
$fieldToName = array_flip($this->databaseFields);<br />
<br />
// Query row data<br />
$query = sprintf("DELETE FROM `%s` WHERE `%s`='%s'",<br />
$this->db->sanitize($this->databaseTable),<br />
$this->db->sanitize($this->databaseFields[$field]),<br />
$this->db->sanitize($this->get($field))<br />
);<br />
<br />
// INFO<br />
$this->info($query);<br />
<br />
// Did we find a row in the database?<br />
if (!$queryData = $this->db->query($query)->fetch()->get())<br />
{<br />
throw new Exception('Failed to delete');<br />
}<br />
<br />
// Success<br />
return true;<br />
}<br />
catch (Exception $e)<br />
{<br />
$this->error('Database Destroy Failed: Class: %s, ID: %s, Error: %s', array(get_class($this), $this->get('id'), $e->getMessage()));<br />
}<br />
<br />
// Fail<br />
return false;<br />
}<br />
<br />
// Error<br />
public function error($txt, $data = array())<br />
{<br />
if ($this->debug)<br />
{<br />
$txt = (is_array($data) && count($data) ? vsprintf($txt, $data) : $txt);<br />
<br />
$GLOBALS['FOGCore']->error(sprintf('Class: %s, Error: %s', get_class($this), $txt));<br />
}<br />
}<br />
<br />
// Info<br />
public function info($txt, $data = array())<br />
{<br />
if ($this->debug)<br />
{<br />
$txt = (is_array($data) && count($data) ? vsprintf($txt, $data) : $txt);<br />
<br />
$GLOBALS['FOGCore']->info(sprintf('Class: %s, Info: %s', get_class($this), $txt));<br />
}<br />
}<br />
<br />
// isValid<br />
public function isValid()<br />
{<br />
// TODO: Add $this->databaseFieldsRequired checks<br />
<br />
if ($this->get('id') || $this->get('name'))<br />
{<br />
return true;<br />
}<br />
<br />
return false;<br />
}<br />
<br />
// isTableDefined <br />
private function isTableDefined()<br />
{<br />
return (!empty($this->databaseTable) ? true : false);<br />
}<br />
<br />
// Name is returned if class is printed<br />
public function __toString()<br />
{<br />
return $this->get('name');<br />
}<br />
}<br />
</pre></div>
Chad-bisd