Zikula_Core
[ class tree: Zikula_Core ] [ index: Zikula_Core ] [ all elements ]

Source for file ObjectUtil.class.php

Documentation is available at ObjectUtil.class.php

  1. <?php
  2. /**
  3.  * Zikula Application Framework
  4.  *
  5.  * @copyright Robert Gasch
  6.  * @link http://www.zikula.org
  7.  * @version $Id: ObjectUtil.class.php 24342 2008-06-06 12:03:14Z markwest $
  8.  * @license GNU/GPL - http://www.gnu.org/copyleft/gpl.html
  9.  * @author Robert Gasch rgasch@gmail.com
  10.  * @package Zikula_Core
  11.  * @subpackage ObjectUtil
  12.  */
  13.  
  14. /**
  15.  * ObjectUtil
  16.  *
  17.  * @package Zikula_Core
  18.  * @subpackage ObjectUtil
  19.  */
  20. class ObjectUtil
  21. {
  22.     /**
  23.      * Add standard PN architecture fields to the table definition
  24.      *
  25.      * @param columns The column list from the PNTables structure for the current table
  26.      * @param col_prefix The column prefix
  27.      *
  28.      * @return Nothing, column array is altered in place
  29.      */
  30.     function addStandardFieldsToTableDefinition (&$columns$col_prefix)
  31.     {
  32.         // ensure correct handling of prefix with and without underscore
  33.         if ($col_prefix)
  34.         {
  35.             $plen strlen($col_prefix);
  36.             if ($col_prefix[$plen-1!= '_')
  37.                 $col_prefix .= '_';
  38.         }
  39.  
  40.         // add standard fields
  41.         $columns['obj_status'$col_prefix 'obj_status';
  42.         $columns['cr_date']    $col_prefix 'cr_date';
  43.         $columns['cr_uid']     $col_prefix 'cr_uid';
  44.         $columns['lu_date']    $col_prefix 'lu_date';
  45.         $columns['lu_uid']     $col_prefix 'lu_uid';
  46.  
  47.         return;
  48.     }
  49.  
  50.  
  51.     /**
  52.      * Generate the SQL to create the standard PN architecture fields
  53.      *
  54.      * @param columns The column list from the PNTables structure for the current table
  55.      *
  56.      * @return The generated SQL string
  57.      */
  58.     function generateCreateSqlForStandardFields ($columns)
  59.     {
  60.         $sql "$columns[obj_status] CHAR(1)  NOT NULL DEFAULT 'A',
  61.                 $columns[cr_date]    DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00',
  62.                 $columns[cr_uid]     INTEGER  NOT NULL DEFAULT '0',
  63.                 $columns[lu_date]    DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00',
  64.                 $columns[lu_uid]     INTEGER  NOT NULL DEFAULT '0'";
  65.  
  66.         return $sql;
  67.     }
  68.  
  69.  
  70.     /**
  71.      * Generate the ADODB DD field descruptors for the standard PN architecture fields
  72.      *
  73.      * @param columns The column list from the PNTables structure for the current table
  74.      *
  75.      * @return The modified list of ADODB DD strings
  76.      */
  77.     function addStandardFieldsToTableDataDefinition (&$columns)
  78.     {
  79.         $columns['obj_status'"C(1) NOTNULL DEFAULT 'A'";
  80.         $columns['cr_date']    "T    NOTNULL DEFAULT '1970-01-01 00:00:00'";
  81.         $columns['cr_uid']     "I    NOTNULL DEFAULT '0'";
  82.         $columns['lu_date']    "T    NOTNULL DEFAULT '1970-01-01 00:00:00'";
  83.         $columns['lu_uid']     "I    NOTNULL DEFAULT '0'";
  84.  
  85.         return;
  86.     }
  87.  
  88.  
  89.     /**
  90.      * Generate the ADODB datadict entries to create the standard PN architecture fields
  91.      *
  92.      * @param $table  The table to add standard fields using ADODB dictionary method
  93.      *
  94.      * @return The generated SQL string
  95.      */
  96.     function generateCreateDataDictForStandardFields ($table)
  97.     {
  98.         $pntables pnDBGetTables();
  99.         $columns  $pntables["{$table}_column"];
  100.         $sql ",
  101.                 $columns[obj_status] C(1) NOTNULL DEFAULT 'A',
  102.                 $columns[cr_date]    T    NOTNULL DEFAULT '1970-01-01 00:00:00',
  103.                 $columns[cr_uid]     I    NOTNULL DEFAULT '0',
  104.                 $columns[lu_date]    T    NOTNULL DEFAULT '1970-01-01 00:00:00',
  105.                 $columns[lu_uid]     I    NOTNULL DEFAULT '0'";
  106.  
  107.         return $sql;
  108.     }
  109.  
  110.  
  111.     /**
  112.      * Set the standard PN architecture fields for object creation/insert
  113.      *
  114.      * @param object         The object we need to set the standard fields on
  115.      * @param preserveValues whether or not to preserve value fields which have a valid value set (optional) (default=false)
  116.      * @param idcolumn       The column name of the primary key column (optional) (default='id')
  117.      *
  118.      * @return Nothing, object is altered in place
  119.      */
  120.     function setStandardFieldsOnObjectCreate (&$obj$preserveValues=false$idcolumn='id')
  121.     {
  122.         if (!is_array ($obj))
  123.         {
  124.             print "ObjectUtil::setStandardFieldsOnObjectUpdate called on non-object:<br />";
  125.             return;
  126.         }
  127.  
  128.         Loader::loadClass ('DateUtil');
  129.  
  130.         $obj[$idcolumnisset($obj[$idcolumn]&& $obj[$idcolumn&& $preserveValues $obj[$idcolumn]  null);
  131.         $obj['cr_date'isset($obj['cr_date']&& $obj['cr_date'&& $preserveValues $obj['cr_date'DateUtil::getDatetime());
  132.         $obj['cr_uid']  isset($obj['cr_uid'])  && $obj['cr_uid']  && $preserveValues $obj['cr_uid']  pnUserGetVar('uid'));
  133.         $obj['lu_date'isset($obj['lu_date']&& $obj['lu_date'&& $preserveValues $obj['lu_date'DateUtil::getDatetime());
  134.         $obj['lu_uid']  isset($obj['lu_uid'])  && $obj['lu_uid']  && $preserveValues $obj['lu_uid']  pnUserGetVar('uid'));
  135.  
  136.         if (is_null($obj['cr_uid'])) {
  137.             $obj['cr_uid'0;
  138.         }
  139.         if (is_null($obj['lu_uid'])) {
  140.             $obj['lu_uid'0;
  141.         }
  142.         return;
  143.     }
  144.  
  145.  
  146.     /**
  147.      * Set the standard PN architecture fields to sane values for an object update
  148.      *
  149.      * @param object         The object we need to set the standard fields on
  150.      * @param preserveValues whether or not to preserve value fields which have a valid value set (optional) (default=false)
  151.      *
  152.      * @return Nothing, object is altered in place
  153.      */
  154.     function setStandardFieldsOnObjectUpdate (&$obj$preserveValues=false)
  155.     {
  156.         if (!is_array ($obj))
  157.         {
  158.             print "ObjectUtil::setStandardFieldsOnObjectUpdate called on non-object:<br />";
  159.             return;
  160.         }
  161.  
  162.         Loader::loadClass ('DateUtil');
  163.  
  164.         $obj['lu_date'isset($obj['lu_date']&& $obj['lu_date'&& $preserveValues $obj['lu_date'DateUtil::getDatetime());
  165.         $obj['lu_uid']  isset($obj['lu_uid'])  && $obj['lu_uid']  && $preserveValues $obj['lu_uid']  pnUserGetVar('uid'));
  166.  
  167.         if (is_null($obj['lu_uid'])) {
  168.             $obj['lu_uid'0;
  169.         }
  170.  
  171.         return;
  172.     }
  173.  
  174.  
  175.     /**
  176.      * Remove the standard fields from the given object
  177.      *
  178.      * @param object    The object to operate on
  179.      *
  180.      * @return Nothing, object is altered in place
  181.      */
  182.     function removeStandardFieldsFromObject (&$obj)
  183.     {
  184.         unset ($obj['obj_status']);
  185.         unset ($obj['cr_date']);
  186.         unset ($obj['cr_uid']);
  187.         unset ($obj['lu_date']);
  188.         unset ($obj['lu_uid']);
  189.  
  190.         return;
  191.     }
  192.  
  193.  
  194.     /**
  195.      * If the specified field is set return it, otherwise return default
  196.      *
  197.      * @param object     The object to get the field from
  198.      * @param field      The field to get
  199.      * @param default     The default value to return if the field is not set on the object (default=null) (optional)
  200.      *
  201.      * @return The object field value or the default
  202.      */
  203.     function getField ($obj$field$default=null)
  204.     {
  205.          if (isset($obj[$field]))
  206.              return $obj[$field];
  207.  
  208.          return $default;
  209.     }
  210.  
  211.  
  212.     /**
  213.      * Create an object of the reuqested type and set the cr_date and cr_uid fields.
  214.      *
  215.      * @param $type     The type of the object to create
  216.      *
  217.      * @return The newly created object
  218.      */
  219.     function createObject ($type)
  220.     {
  221.         $pntable pnDBGetTables();
  222.         if (!$pntable[$type])
  223.             return pn_exit ("ObjectUtil::createObject: unable to reference object type [$type]");
  224.  
  225.         Loader::loadClass ('DateUtil');
  226.         $objarray ();
  227.         $obj['__TYPE__'$type;
  228.         $obj['cr_date']  DateUtil::getDateTime ();
  229.         $obj['cr_uid']   pnUserGetVar('uid');
  230.  
  231.         return $obj;
  232.     }
  233.  
  234.  
  235.     /**
  236.      * Diff 2 objects/arrays
  237.      *
  238.      * @param object1     The first array/object
  239.      * @param object2     The second object/array
  240.      *
  241.      * @return The difference between the two objects
  242.      */
  243.     function diff ($obj1$obj2)
  244.     {
  245.         if (!is_array ($obj1))
  246.             return pn_exit ("ObjectUtil::diff: object1 is not an object ... ");
  247.         if (!is_array ($obj2))
  248.             return pn_exit ("ObjectUtil::diff: object2 is not an object ... ");
  249.  
  250.         return array_diff ($obj1$obj2);
  251.     }
  252.  
  253.  
  254.     /**
  255.      * Provide an informative extended diff array when comparing 2 arrays
  256.      *
  257.      * @param a1        Array 1
  258.      * @param a2        Array 2
  259.      * @param detail    whether or not to give detailed update info (optional (default=false)
  260.      * @param recurse   whether or not to recurse (optional) (default=true)
  261.      *
  262.      * @return data array containing the diff results
  263.      */
  264.     function diffExtended ($a1$a2$detail=false$recurse=true)
  265.     {
  266.         $res array();
  267.  
  268.         if (!is_array($a1|| !is_array($a2))
  269.             return $res;
  270.  
  271.         foreach ($a1 as $k => $v)
  272.         {
  273.             if (is_array ($v))
  274.         {
  275.                 if ($recurse)
  276.                     $res[$kObjectUtil::diff ($v$a2[$k]$detail);
  277.         }
  278.             else
  279.             if (!isset($a2[$k]))
  280.                 $res[$k'I: ' $v;
  281.             else
  282.             if ($v !== $a2[$k])
  283.             {
  284.                 if ($detail)
  285.                 {
  286.                     $res[$karray ();
  287.                     $res[$k]['old'$v;
  288.                     $res[$k]['new'$a2[$k];
  289.                 }
  290.                 else
  291.                     $res[$k'U: ' $a2[$k];
  292.             }
  293.  
  294.             unset ($a2[$k]);
  295.         }
  296.  
  297.         foreach ($a2 as $k => $v)
  298.         {
  299.             if (is_array ($v))
  300.             {
  301.                 if ($recurse)
  302.                     $res[$kObjectUtil::diff ($a1[$k]$v$detail);
  303.             }
  304.             else
  305.                 $res[$k'D: ' $v;
  306.         }
  307.  
  308.         return $res;
  309.     }
  310.  
  311.  
  312.     /**
  313.      * Fixes the sequence numbers (column position) in a given table.
  314.      * Needed, if an object was added or deleted in a table using the
  315.      * arrow up/down feature.
  316.      *
  317.      * @param tablename   The tablename key for the PNTables structure
  318.      * @param field       The name of the field we wish to resequence (optional) (default='position')
  319.      * @param float       whether or not to use a float (optional) (default=false (uses integer))
  320.      * @param idcolumn    The column which contains the unique ID
  321.      *
  322.      * @return nothing 
  323.      */
  324.     function resequenceFields ($tablename$field='position'$float=false$idcolumn='id')
  325.     {
  326.         $pntables pnDBGetTables();
  327.         $column   $pntables["{$tablename}_column"];
  328.         $tab      $pntables[$tablename];
  329.  
  330.         if (!$column[$field])
  331.             return pn_exit ("ObjectUtil::resequenceFields: there is no [$field] field in the [$tablename] table... ");
  332.  
  333.         $sql "SELECT $column[$idcolumn]$column[$field]
  334.                 FROM $tab
  335.                 ORDER BY $column[$field]";
  336.         $res DBUtil::executeSQL ($sql);
  337.  
  338.         $seq ($float 1.0 1);
  339.         while(list($id$curseq$res->fields)
  340.         {
  341.             $res->MoveNext();
  342.             if ($curseq != $seq)
  343.             {
  344.                 $sql "UPDATE $tab SET $column[$field] = '".DataUtil::formatForStore($seq)."' WHERE $column[$idcolumn]='DataUtil::formatForStore($id"'";
  345.                 $upd DBUtil::executeSQL ($sql);
  346.             }
  347.             $seq += 1;
  348.         }
  349.     }
  350.  
  351.  
  352.     /**
  353.      * Increments or decremnts a sequence number (column position) in a table for
  354.      * a given ID. If exists, it swaps the sequence of the field above or down.
  355.      *
  356.      * @param object     The object we wish to increment or decrement
  357.      * @param tablename  The tablename key for the PNTables structure
  358.      * @param direction  whether we want to increment or decrement the position of the object. Possible values are 'up' (default) and 'down'
  359.      * @param field      The name of the field we wish to resequence
  360.      * @param idcolumn   The column which contains the unique ID
  361.      * @param field2     An additional field to consider in the where-clause
  362.      * @param value2     An additional value to consider in the where-clause
  363.      *
  364.      * @return true/false on success/failure
  365.      */
  366.     function moveField ($obj$tablename$direction='up'$field='position'$idcolumn='id',
  367.                         $field2=''$value2='')
  368.     {
  369.         if (!is_array ($obj))
  370.             return pn_exit ("ObjectUtil::moveField: object is not an array ... ");
  371.  
  372.         if (!isset($obj[$idcolumn]))
  373.             return pn_exit ("ObjectUtil::moveField: no object ID ... ");
  374.  
  375.         $pntables pnDBGetTables();
  376.         $column   $pntables["{$tablename}_column"];
  377.         $tab      =  $pntables[$tablename];
  378.  
  379.         if (!$column[$field])
  380.             return pn_exit ("ObjectUtil::moveField: there is no $field field in the specified table... ");
  381.  
  382.         // Get info on current position of field
  383.         $where "$column[$idcolumn]='DataUtil::formatForStore($obj[$idcolumn]"'";
  384.         $seq DBUtil::selectField($tablename$field$where);
  385.  
  386.         // Get info on displaced field
  387.         $direction strtolower ($direction);
  388.         $where2 '';
  389.         if ($field2 && $value2{
  390.             $where2 " AND $column[$field2]='DataUtil::formatForStore($value2"'";
  391.         }
  392.  
  393.         if ($direction == 'up'{
  394.             $sql "SELECT $column[$idcolumn]$column[$field]
  395.                     FROM $tab
  396.                     WHERE $column[$field] < 'DataUtil::formatForStore($seq"$where2
  397.                     ORDER BY $column[$field] DESC LIMIT 0,1";
  398.         }else if ($direction == 'down'{
  399.             $sql "SELECT $column[$idcolumn]$column[$field]
  400.                     FROM $tab
  401.                     WHERE $column[$field] > 'DataUtil::formatForStore($seq"$where2
  402.                     ORDER BY $column[$field] ASC LIMIT 0,1";
  403.         else {
  404.             return pn_exit ("ObjectUtil::moveField: invalid direction [$direction] supplied ... ");
  405.         }
  406.  
  407.         $res DBUtil::executeSQL ($sql);
  408.         if ($res->EOF)  // No field directly above or below that one
  409.             return false;
  410.  
  411.         list($altid$altseq$res->fields;
  412.  
  413.         // Swap sequence numbers
  414.         $sql "UPDATE $tab SET $column[$field]='DataUtil::formatForStore($seq."' WHERE $column[$idcolumn]='DataUtil::formatForStore($altid"'";
  415.         $upd1 DBUtil::executeSQL ($sql);
  416.         $sql "UPDATE $tab SET $column[$field]='DataUtil::formatForStore($altseq"' WHERE $column[$idcolumn]='DataUtil::formatForStore($obj[$idcolumn]"'";
  417.         $upd2 DBUtil::executeSQL ($sql);
  418.  
  419.         return true;
  420.     }
  421.  
  422.  
  423.     /**
  424.      * Retrieve the attribute maps for the specified object
  425.      *
  426.      * @param object     The object whose attribute we wish to retrieve
  427.      * @param type       The type of the given object
  428.      * @param idcolumn   The column which holds the ID value (optional) (default='id')
  429.      *
  430.      * @return The object attribute (array)
  431.      */
  432.     function retrieveObjectAttributes ($obj$type$idcolumn='id')
  433.     {
  434.         if (!$obj)
  435.             return pn_exit ('Invalid object passed to ObjectUtil::retrieveObjectAttributes ...');
  436.  
  437.         if (!$type)
  438.             return pn_exit ('Invalid type passed to ObjectUtil::retrieveObjectAttributes ...');
  439.  
  440.         // ensure that only objects with a valid ID are used
  441.         if (!$obj[$idcolumn])
  442.             return false;
  443.  
  444.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  445.             return false;
  446.  
  447.         $pntables       pnDBGetTables();
  448.         $objattr_table  $pntables['objectdata_attributes'];
  449.         $objattr_column $pntables['objectdata_attributes_column'];
  450.  
  451.         $where "WHERE $objattr_column[object_id]= '".DataUtil::formatForStore($obj[$idcolumn])."' AND
  452.                         $objattr_column[object_type]='".DataUtil::formatForStore($type)."'";
  453.  
  454.         $objArray DBUtil::selectObjectArray ('objectdata_attributes'$where);
  455.         return $objArray;
  456.     }
  457.  
  458.  
  459.     /**
  460.      * Expand the given object with it's attributes
  461.      *
  462.      * @param object     The object whose attribute we wish to retrieve
  463.      * @param type       The type of the given object
  464.      * @param idcolumn   The column which holds the ID value (optional) (default='id')
  465.      *
  466.      * @return The object which has been altered in place
  467.      */
  468.     function expandObjectWithAttributes (&$obj$type$idcolumn='id')
  469.     {
  470.         if (!isset($obj[$idcolumn]|| !$obj[$idcolumn])
  471.             return pn_exit ("Unable to determine a valid ID in object [$type$idcolumn] ...");
  472.  
  473.         $atrs ObjectUtil::retrieveObjectAttributes ($obj$type$idcolumn);
  474.         if (!$atrs)
  475.             return false;
  476.  
  477.         foreach($atrs as $atr{
  478.             $obj['__ATTRIBUTES__'][$atr['attribute_name']] $atr['value'];
  479.         }
  480.         return $obj;
  481.     }
  482.  
  483.  
  484.  
  485.     /**
  486.      * Store the attributes for the given objects.
  487.      *
  488.      * @param object     The object whose attributes we wish to store
  489.      * @param type       The type of the given object
  490.      * @param idcolumn   The idcolumn of the object (optional) (default='id')
  491.      *
  492.      * @return true/false on success/failure
  493.      */
  494.     function storeObjectAttributes ($obj$type$idcolumn='id')
  495.     {
  496.         if (!$obj)
  497.             return pn_exit ('Invalid object passed to ObjectUtil::storeObjectAttributes ...');
  498.  
  499.         if (!$type)
  500.             return pn_exit ('Invalid type passed to ObjectUtil::storeObjectAttributes ...');
  501.  
  502.         if (!$idcolumn)
  503.             return pn_exit ('Invalid idcolumn passed to ObjectUtil::storeObjectAttributes ...');
  504.  
  505.         if (!isset($obj['__ATTRIBUTES__']|| !is_array($obj['__ATTRIBUTES__']))
  506.             return false;
  507.  
  508.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  509.             return false;
  510.  
  511.         $pntables       pnDBGetTables();
  512.         $objattr_table  $pntables['objectdata_attributes'];
  513.         $objattr_column $pntables['objectdata_attributes_column'];
  514.  
  515.         $objID $obj[$idcolumn];
  516.         if (!$objID)
  517.             return pn_exit ('storeObjectAttributes: Unable to determine object ID ... ');
  518.  
  519.         // delete old attribute values for this object
  520.         $sql "DELETE FROM $objattr_table WHERE $objattr_column[object_type] = 'DataUtil::formatForStore($type"' AND
  521.                                                  $objattr_column[object_id] = 'DataUtil::formatForStore($objID"'";
  522.         DBUtil::executeSQL ($sql);
  523.  
  524.         $atrs (isset($obj['__ATTRIBUTES__']$obj['__ATTRIBUTES__'null);
  525.         if (!$atrs)
  526.             return true;
  527.  
  528.         // process all the attribute fields
  529.         $tobj array ();
  530.         foreach ($atrs as $k => $v)
  531.         {
  532.             if (strlen($v))
  533.             {
  534.                 $tobj['attribute_name'$k;
  535.                 $tobj['object_id']      $objID;
  536.                 $tobj['object_type']    $type;
  537.                 $tobj['value']          $v;
  538.  
  539.                 DBUtil::insertObject ($tobj'objectdata_attributes');
  540.             }
  541.         }
  542.  
  543.         return true;
  544.     }
  545.  
  546.  
  547.     /**
  548.      * Delete the attributes for the given object.
  549.      *
  550.      * @param object     The object whose attributes we wish to store
  551.      * @param type       The type of the given object
  552.      * @param idcolumn   The idcolumn of the object (optional) (default='id')
  553.      *
  554.      * @return the SQL result of the delete operation
  555.      */
  556.     function deleteObjectAttributes (&$obj$type$idcolumn='id')
  557.     {
  558.         if (!$obj)
  559.             return pn_exit ('Invalid object passed to ObjectUtil::deleteObjectAttributes ...');
  560.  
  561.         if (!$type)
  562.             return pn_exit ('Invalid type passed to ObjectUtil::deleteObjectAttributes ...');
  563.  
  564.         if (!$idcolumn)
  565.             return pn_exit ('Invalid idcolumn passed to ObjectUtil::deleteObjectAttributes ...');
  566.  
  567.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  568.             return false;
  569.  
  570.         $pntables       pnDBGetTables();
  571.         $objattr_table  $pntables['objectdata_attributes'];
  572.         $objattr_column $pntables['objectdata_attributes_column'];
  573.  
  574.         // ensure module was successfully loaded
  575.         if (!$objattr_table)
  576.             return false;
  577.  
  578.         $objID $obj[$idcolumn];
  579.         if (!$objID)
  580.             return pn_exit ('storeObjectAttributes: Unable to determine object ID ... ');
  581.  
  582.         $sql "DELETE FROM $objattr_table WHERE $objattr_column[object_type] = 'DataUtil::formatForStore($type"' AND
  583.                                                  $objattr_column[object_id] = 'DataUtil::formatForStore($objID"'";
  584.         $res DBUtil::executeSQL ($sql);
  585.         return $res;
  586.     }
  587.  
  588.  
  589.     /**
  590.      * Delete the all attributes for the given tab
  591.      *
  592.      * @param type       The type/tablename we wish to delete attributes for
  593.      *
  594.      * @return the SQL result of the delete operation
  595.      */
  596.     function deleteAllObjectTypeAttributes ($type)
  597.     {
  598.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  599.             return false;
  600.  
  601.         $pntables       pnDBGetTables();
  602.         $objattr_table  $pntables['objectdata_attributes'];
  603.         $objattr_column $pntables['objectdata_attributes_column'];
  604.  
  605.         $sql "DELETE FROM $objattr_table WHERE $objattr_column[object_type] = 'DataUtil::formatForStore($type"'";
  606.         $res DBUtil::executeSQL ($sql);
  607.         return $res;
  608.     }
  609.  
  610.  
  611.     /**
  612.      * Retrieve a list of attributes defined in the system
  613.      *
  614.      * @param sort         The column to sort by (optional) (default='attribute_name')
  615.      *
  616.      * @return the system attributes field array
  617.      */
  618.     function getSystemAttributes ($sort='attribute_name')
  619.     {
  620.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  621.             return false;
  622.  
  623.         $pntables       pnDBGetTables();
  624.         $objattr_table  $pntables['objectdata_attributes'];
  625.         $objattr_column $pntables['objectdata_attributes_column'];
  626.  
  627.         // ensure module was successfully loaded
  628.         if (!$objattr_table)
  629.             return false;
  630.  
  631.         $atrs DBUtil::selectFieldArray ('objectdata_attributes''attribute_name''''attribute_name'true);
  632.         return $atrs;
  633.     }
  634.  
  635.  
  636.     /**
  637.      * Retrieve the count for a given attribute name
  638.      *
  639.      * @param atrName     The name of the attribute
  640.      *
  641.      * @return The count for the given attribute
  642.      */
  643.     function getAttributeCount ($atrName)
  644.     {
  645.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  646.             return false;
  647.  
  648.         $pntables       pnDBGetTables();
  649.         $objattr_column $pntables['objectdata_attributes_column'];
  650.  
  651.         $where "$objattr_column[attribute_name]='".DataUtil::formatForStore($atrName)."'";
  652.         return DBUtil::selectObjectCount ('objectdata_attributes'$where);
  653.     }
  654.  
  655.  
  656.     /**
  657.      * Ensure that a meta-data object has reasonable default values
  658.      *
  659.      * @param obj        The object we wish to store metadata for
  660.      * @param tablename  The object's tablename
  661.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  662.      *
  663.      * @return Altered meta object (meta object is also altered in place)
  664.      */
  665.     function fixObjectMetaData (&$obj$tablename$idcolumn)
  666.     {
  667.         if (!isset($obj['__META__']|| !is_array($obj['__META__']))
  668.             $obj['__META__'array ();
  669.  
  670.         $meta =$obj['__META__'];
  671.  
  672.         $meta['table']    $tablename;
  673.         $meta['idcolumn'$idcolumn;
  674.  
  675.         if (!isset($meta['module']|| !$meta['module'])
  676.             $meta['module'pnModGetName ();
  677.  
  678.         if (!isset($meta['obj_id']|| !$meta['obj_id'])
  679.             $meta['obj_id'(isset($obj[$idcolumn]$obj[$idcolumn: -1);
  680.  
  681.         return $meta;
  682.     }
  683.  
  684.  
  685.     /**
  686.      * Insert a meta data object
  687.      *
  688.      * @param obj        The object we wish to store metadata for
  689.      * @param tablename  The object's tablename
  690.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  691.      *
  692.      * @return The result from the metadata insert operation
  693.      */
  694.     function insertObjectMetaData (&$obj$tablename$idcolumn='id')
  695.     {
  696.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  697.             return false;
  698.  
  699.         $meta ObjectUtil::fixObjectMetaData ($obj$tablename$idcolumn);
  700.         if ($meta['obj_id'0)
  701.         {
  702.             $result DBUtil::insertObject ($meta'objectdata_meta');
  703.             $obj['__META__']['metaid'$meta['id'];
  704.             return $meta['id'];
  705.         }
  706.  
  707.         return false;
  708.     }
  709.  
  710.  
  711.     /**
  712.      * Update a meta data object
  713.      *
  714.      * @param obj        The object we wish to store metadata for
  715.      * @param tablename  The object's tablename
  716.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  717.      *
  718.      * @return The result from the metadata insert operation
  719.      */
  720.     function updateObjectMetaData (&$obj$tablename$idcolumn='id')
  721.     {
  722.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  723.             return false;
  724.  
  725.         if (!isset($obj['__META__']['id'])) {
  726.             return false;
  727.         }
  728.  
  729.         $meta $obj['__META__'];
  730.         if ($meta['obj_id'0{
  731.             return DBUtil::updateObject ($meta'objectdata_meta');
  732.         }
  733.  
  734.         return true;
  735.     }
  736.  
  737.  
  738.     /**
  739.      * Delete a meta data object
  740.      *
  741.      * @param obj        The object we wish to delete metadata for
  742.      * @param tablename  The object's tablename
  743.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  744.      *
  745.      * @return The result from the metadata insert operation
  746.      */
  747.     function deleteObjectMetaData (&$obj$tablename$idcolumn='id')
  748.     {
  749.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  750.             return false;
  751.  
  752.         ObjectUtil::fixObjectMetaData ($obj$tablename$idcolumn);
  753.  
  754.         if (isset($obj['__META__']['id']&& $obj['__META__']['id'])
  755.             $rc DBUtil::deleteObjectByID ($obj['__META__']'objectdata_meta');
  756.         else
  757.         if (isset($obj['__META__']['idcolumn']&& $obj['__META__']['obj_id'])
  758.         {
  759.             $pntables    pnDBGetTables();
  760.             $meta_column $pntables['objectdata_meta_column'];
  761.  
  762.             $meta $obj['__META__'];
  763.             $where "WHERE $meta_column[module]='".DataUtil::formatForStore($meta[module])."'
  764.                         AND $meta_column[table]='".DataUtil::formatForStore($meta[table])."'
  765.                         AND $meta_column[idcolumn]='".DataUtil::formatForStore($meta[idcolumn])."'
  766.                         AND $meta_column[obj_id]='".DataUtil::formatForStore($meta[obj_id])."'";
  767.  
  768.             $rc DBUtil::deleteObject(array()'objectdata_meta'$where);
  769.         }
  770.  
  771.         return (boolean)$rc;
  772.     }
  773.  
  774.  
  775.     /**
  776.      * Retrieve object meta data
  777.      *
  778.      * @param obj        The object we wish to retrieve metadata for
  779.      * @param tablename  The object's tablename
  780.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  781.      *
  782.      * @return The object with the meta data filled in
  783.      */
  784.     function retrieveObjectMetaData (&$obj$tablename$idcolumn='id')
  785.     {
  786.         if (!pnModAvailable('ObjectData'|| !pnModDBInfoLoad ('ObjectData'))
  787.             return false;
  788.  
  789.         $meta ObjectUtil::fixObjectMetaData ($obj$tablename$idcolumn);
  790.         if ($meta['obj_id'0)
  791.         {
  792.             $pntables       pnDBGetTables();
  793.             $meta_column $pntables['objectdata_meta_column'];
  794.  
  795.             $where "WHERE $meta_column[module]='".DataUtil::formatForStore($meta[module])."'
  796.                         AND $meta_column[table]='".DataUtil::formatForStore($meta[table])."'
  797.                         AND $meta_column[idcolumn]='".DataUtil::formatForStore($meta[idcolumn])."'
  798.                         AND $meta_column[obj_id]='".DataUtil::formatForStore($meta[obj_id])."'";
  799.  
  800.             return DBUtil::selectObject ('objectdata_meta'$where);
  801.         }
  802.  
  803.         return true;
  804.     }
  805.  
  806.  
  807.     /**
  808.      * Expand an object with it's Meta data
  809.      *
  810.      * @param obj        The object we wish to get the metadata for
  811.      * @param tablename  The object's tablename
  812.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  813.      *
  814.      * @return The object with the meta data filled in. The object passed in is altered in place
  815.      */
  816.     function expandObjectWithMeta (&$obj$tablename$idcolumn='id')
  817.     {
  818.         if (!isset($obj[$idcolumn]|| !$obj[$idcolumn])
  819.             return pn_exit ("Unable to determine a valid ID in object [$type$idcolumn] ...");
  820.  
  821.         $meta ObjectUtil::retrieveObjectMetaData ($obj$tablename$idcolumn);
  822.         if (!$meta)
  823.             return false;
  824.  
  825.         $obj['__META__'$meta;
  826.         return $obj;
  827.     }
  828.  
  829.  
  830.     /**
  831.      * Insert a categorization data object
  832.      *
  833.      * @param obj        The object we wish to store categorization data for
  834.      * @param tablename  The object's tablename
  835.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  836.      *
  837.      * @return The result from the category data insert operation
  838.      */
  839.     function storeObjectCategories ($obj$tablename$idcolumn='id')
  840.     {
  841.         if (!$obj)
  842.             return pn_exit ('Invalid object passed to ObjectUtil::storeObjectCategories ...');
  843.  
  844.         if (!$tablename)
  845.             return pn_exit ('Invalid tablename passed to ObjectUtil::storeObjectCategories ...');
  846.  
  847.         if (!$idcolumn)
  848.             return pn_exit ('Invalid idcolumn passed to ObjectUtil::storeObjectCategories ...');
  849.  
  850.         if (!pnModDBInfoLoad ('Categories'))
  851.             return false;
  852.  
  853.         if (!isset($obj['__CATEGORIES__']|| !is_array($obj['__CATEGORIES__']|| !$obj['__CATEGORIES__'])
  854.             return false;
  855.  
  856.         ObjectUtil::deleteObjectCategories ($obj$tablename$idcolumn);
  857.  
  858.         // ensure that we don't store duplicate object mappings
  859.         $values array();
  860.         foreach ($obj['__CATEGORIES__'as $k=>$v)
  861.         {
  862.             if (isset($values[$v]))
  863.                 unset ($obj['__CATEGORIES__'][$k]);
  864.             else
  865.                 $values[$v1;
  866.         }
  867.  
  868.         // Get the ids of the categories properties of the object
  869.         $modname = isset($obj['__META__']['module']$obj['__META__']['module'pnModGetName();
  870.         Loader::loadClass('CategoryRegistryUtil');
  871.         $reg_ids CategoryRegistryUtil::getRegisteredModuleCategoriesIds($modname$tablename);
  872.  
  873.         $cobj array();
  874.         $cobj['table']        $tablename;
  875.         $cobj['obj_idcolumn'$idcolumn;
  876.  
  877.         $res true;
  878.         foreach ($obj['__CATEGORIES__'as $prop => $cat)
  879.         {
  880.             // if there's all the data and the Registry exists
  881.             // the category is mapped
  882.             if ($cat && $prop && isset($reg_ids[$prop]))
  883.             {
  884.                 $cobj['id']           '';
  885.                 $cobj['modname']      $modname;
  886.                 $cobj['obj_id']       $obj[$idcolumn];
  887.                 $cobj['category_id']  $cat;
  888.                 $cobj['reg_id']       $reg_ids[$prop];
  889.  
  890.                 $res DBUtil::insertObject ($cobj'categories_mapobj');
  891.             }
  892.         }
  893.  
  894.         return (boolean)$res;
  895.     }
  896.  
  897.  
  898.     /**
  899.      * Delete a meta data object
  900.      *
  901.      * @param obj        The object we wish to delete categorization data for
  902.      * @param tablename  The object's tablename
  903.      * @param idcolumn   The object's idcolumn (optional) (default='obj_id')
  904.      *
  905.      * @return The result from the metadata insert operation
  906.      */
  907.     function deleteObjectCategories ($obj$tablename$idcolumn='obj_id')
  908.     {
  909.         if (!pnModDBInfoLoad ('Categories'))
  910.             return false;
  911.  
  912.         $where "cmo_table='".DataUtil::formatForStore($tablename)."' AND cmo_obj_id='".
  913.                                DataUtil::formatForStore($obj[$idcolumn])."' AND cmo_obj_idcolumn='".
  914.                                DataUtil::formatForStore($idcolumn)."'";
  915.         return (boolean) DBUtil::deleteWhere ('categories_mapobj'$where);
  916.     }
  917.  
  918.  
  919.     /**
  920.      * Retrieve object category data
  921.      *
  922.      * @param obj        The object we wish to retrieve metadata for
  923.      * @param tablename  The object's tablename
  924.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  925.      *
  926.      * @return The object with the meta data filled in
  927.      */
  928.     function retrieveObjectCategoriesList ($obj$tablename$idcolumn='id')
  929.     {
  930.         static $cache;
  931.  
  932.         $key $tablename '_' $obj[$idcolumn];
  933.         if (isset($cache[$key])) {
  934.             return $cache[$key];
  935.         }
  936.  
  937.         if (!pnModDBInfoLoad ('Categories'))
  938.             return false;
  939.  
  940.         $pntabs pnDBGetTables();
  941.         $cat    $pntabs ['categories_mapobj_column'];
  942.         pnModLangLoad('Categories''common');
  943.  
  944.         $where "WHERE tbl.$cat[table]='".DataUtil::formatForStore($tablename)."
  945.                     AND tbl.$cat[obj_idcolumn]='".DataUtil::formatForStore($idcolumn)."'
  946.                     AND tbl.$cat[obj_id]='".DataUtil::formatForStore($obj[$idcolumn])."'";
  947.         $orderby "ORDER BY tbl.$cat[category_id]";
  948.  
  949.         $joinInfo[array('join_table' => 'categories_registry',
  950.                             'join_field' => 'property',
  951.                             'object_field_name' => 'property',
  952.                             'compare_field_table' => 'reg_id',
  953.                             'compare_field_join' => 'id');
  954.  
  955.         $cache[$keyDBUtil::selectExpandedFieldArray('categories_mapobj'$joinInfo'category_id'$where$orderbyfalse'property');
  956.         return $cache[$key];
  957.     }
  958.  
  959.  
  960.     /**
  961.      * Retrieve object category data
  962.      *
  963.      * @param obj        The object we wish to retrieve metadata for
  964.      * @param tablename  The object's tablename
  965.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  966.      * @param assocKey   The field to use for the associative array index (optional) (default='id')
  967.      *
  968.      * @return The object with the meta data filled in
  969.      */
  970.     function retrieveObjectCategoriesObjects ($obj$tablename$idcolumn='id'$assocKey=''$enablePermissionCheck=true)
  971.     {
  972.         if (!Loader::loadClass('CategoryUtil'))
  973.             return pn_exit ("Unable to load array class [CategoryUtil] ...");
  974.  
  975.         $catlist ObjectUtil::retrieveObjectCategoriesList ($obj$tablename$idcolumn);
  976.         if (!$catlist)
  977.             return array();
  978.  
  979.         $cats  implode (','array_values($catlist));
  980.         $where "WHERE cat_id IN ($cats)";
  981.         $catsdata CategoryUtil::getCategories ($where'''id'$enablePermissionCheck);
  982.  
  983.         $result array();
  984.         foreach ($catlist as $prop => $cat{
  985.             if (isset($catsdata[$cat])) {
  986.                 $result[$prop$catsdata[$cat];
  987.             }
  988.         }
  989.         return $result;
  990.     }
  991.  
  992.  
  993.     /**
  994.      * Expand an object array with it's category data
  995.      *
  996.      * @param objArray   The object array we wish to get the category for
  997.      * @param tablename  The object's tablename
  998.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  999.      * @param field      The category field to return the object's category info (optional) (default='id')
  1000.      *
  1001.      * @return The object with the meta data filled in. The object passed in is altered in place
  1002.      */
  1003.     function expandObjectArrayWithCategories (&$objArray$tablename$idcolumn='id'$field='id'$locale='eng')
  1004.     {
  1005.         if (!pnModDBInfoLoad ('Categories'))
  1006.             return false;
  1007.  
  1008.         if (!$objArray || !is_array($objArray))
  1009.             return false;
  1010.  
  1011.         $pntabs pnDBGetTables();
  1012.         $tab    $pntabs ['categories_mapobj'];
  1013.         $col    $pntabs ['categories_mapobj_column'];
  1014.         pnModLangLoad('Categories''common');
  1015.  
  1016.         $w1 array();
  1017.         $w2 array();
  1018.         foreach ($objArray as $obj)
  1019.             $w1[DataUtil::formatForStore($obj[$idcolumn]);
  1020.  
  1021.         $t implode (','$w1);
  1022.         $w2["tbl.$col[obj_id] IN ($t ')';
  1023.         $w2["tbl.$col[table]='".DataUtil::formatForStore($tablename)."' AND tbl.$col[obj_idcolumn]='".DataUtil::formatForStore($idcolumn)."' ";
  1024.         $where "WHERE " implode (' AND '$w2);
  1025.         $sort  "ORDER BY tbl.$col[obj_id], tbl.$col[category_id]";
  1026.  
  1027.         $joinInfo[array('join_table' => 'categories_registry',
  1028.                             'join_field' => 'property',
  1029.                             'object_field_name' => 'property',
  1030.                             'compare_field_table' => 'reg_id',
  1031.                             'compare_field_join' => 'id');
  1032.  
  1033.         $maps DBUtil::selectExpandedObjectArray ('categories_mapobj'$joinInfo$where$sort);
  1034.         if (!$maps)
  1035.             return false;
  1036.  
  1037.         // since we don't know the order in which our data array will be, we
  1038.         // have to do this iteratively. However, this is still a lot faster
  1039.         // than doing a select for every data line.
  1040.         $catlist array();
  1041.         foreach ($objArray as $k => $obj)
  1042.         {
  1043.             $last null;
  1044.             foreach ($maps as $map)
  1045.             {
  1046.                 if ($map['obj_id'== $obj[$idcolumn])
  1047.                 {
  1048.                     $last  $map['obj_id'];
  1049.                     $prop  $map['property'];
  1050.                     $catid $map['category_id'];
  1051.                     $objArray[$k]['__CATEGORIES__'][$prop$catid;
  1052.                     $catlist[$catid;
  1053.                 }
  1054.  
  1055.                 if ($last && $last != $map['obj_id'])
  1056.                     break;
  1057.             }
  1058.         }
  1059.  
  1060.         // now retrieve the full category data
  1061.         $where 'WHERE cat_id IN ('implode(',',$catlist')';
  1062.  
  1063.         //$cats  = DBUtil::selectObjectArray ('categories_category', $where, '', -1, -1, 'id');
  1064.         if (!($catClassLoader::loadClassFromModule ('Categories''category'true)))
  1065.             return pn_exit ("Unable to load array class [category] ...");
  1066.         $catArray new $catClass();
  1067.         $data $catArray->get ($where''-1-1'id');
  1068.  
  1069.         // use the cagtegory map created previously to build the object category array
  1070.         foreach ($objArray as $k => $obj)
  1071.         {
  1072.             foreach ($obj['__CATEGORIES__'as $prop => $cat)
  1073.             {
  1074.                 $data[$cat]['path'str_replace('__SYSTEM__'_CATEGORIES_ROOTCAT$data[$cat]['path']);
  1075.                 $objArray[$k]['__CATEGORIES__'][$prop$data[$cat];
  1076.             }
  1077.         }
  1078.  
  1079.         // now generate the relative paths
  1080.         //$rootCatID = CategoryRegistryUtil::getRegisteredModuleCategory (pnModGetName(), $tablename, 'main_table', '/__SYSTEM__/Modules/Quotes/Default');
  1081.         //postProcessExpandedObjectArrayCategories ($objArray, $rootCatID, false);
  1082.  
  1083.         return $objArray;
  1084.     }
  1085.  
  1086.  
  1087.     /**
  1088.      * Expand an object with it's category data
  1089.      *
  1090.      * @param obj        The object we wish to get the metadata for
  1091.      * @param tablename  The object's tablename
  1092.      * @param idcolumn   The object's idcolumn (optional) (default='id')
  1093.      * @param field      The category field to return the object's category info (optional) (default='id')
  1094.      * @param assocKey   The field to use for the associative array index (optional) (default='id')
  1095.      *
  1096.      * @return The object with the meta data filled in. The object passed in is altered in place
  1097.      */
  1098.     function expandObjectWithCategories (&$obj$tablename$idcolumn='id'$assocKey='')
  1099.     {
  1100.         if (!isset($obj[$idcolumn]|| !$obj[$idcolumn])
  1101.             return pn_exit ("Unable to determine a valid ID in object [$type$idcolumn] ...");
  1102.  
  1103.         if (!pnModDBInfoLoad ('Categories'))
  1104.             return false;
  1105.  
  1106.         $cats ObjectUtil::retrieveObjectCategoriesObjects ($obj$tablename$idcolumn$assocKeyfalse);
  1107.         $obj['__CATEGORIES__'$cats;
  1108.  
  1109.         // now generate the relative paths
  1110.         //$module = pnModGetName();
  1111.         //$rootCatID = CategoryRegistryUtil::getRegisteredModuleCategory (pnModGetName(), $tablename, 'main_table', '/__SYSTEM__/Modules/Quotes/Default');
  1112.         //postProcessExpandedObjectCategories ($obj, $rootCatID);
  1113.  
  1114.         return $obj;
  1115.     }
  1116.  
  1117.  
  1118.     /**
  1119.      * Post-process an object-array's expanded categories to generate relative paths
  1120.      *
  1121.      * @param objArray    The object array we wish to post-process
  1122.      * @param rootCatID   The root category ID for the relative path creation
  1123.      * @param includeRoot whether or not to include the root folder in the relative path (optional) (default=false)
  1124.      *
  1125.      * @return The object-array with the additionally expanded category data is altered in place and returned
  1126.      */
  1127.     function postProcessExpandedObjectArrayCategories (&$objArray$rootCats$includeRoot=false)
  1128.     {
  1129.         if (!$objArray)
  1130.             return pn_exit ("Invalid object in postProcessExpandedObjectArrayCategories ...");
  1131.  
  1132.         $ak array_keys($objArray);
  1133.         foreach ($ak as $k{
  1134.             if (isset($objArray[$k]['__CATEGORIES__']&& $objArray[$k]['__CATEGORIES__']{
  1135.                 ObjectUtil::postProcessExpandedObjectCategories ($objArray[$k]['__CATEGORIES__']$rootCats$includeRoot);
  1136.             }
  1137.         }
  1138.  
  1139.         return $objArray;
  1140.     }
  1141.  
  1142.  
  1143.     /**
  1144.      * Post-process an object's expanded category data to generate relative paths
  1145.      *
  1146.      * @param obj         The object we wish to post-process
  1147.      * @param rootCat     The root category ID for the relative path creation
  1148.      * @param includeRoot whether or not to include the root folder in the relative path (optional) (default=false)
  1149.      *
  1150.      * @return The object with the additionally expanded category data is altered in place and returned
  1151.      */
  1152.     function postProcessExpandedObjectCategories (&$obj$rootCatsIDs$includeRoot=false)
  1153.     {
  1154.         if (!$obj)
  1155.             return pn_exit ("Invalid object in postProcessExpandedObjectCategories ...");
  1156.  
  1157.         if (!Loader::loadClass('CategoryUtil'))
  1158.             return pn_exit ("Unable to load array class [CategoryUtil] ...");
  1159.  
  1160.         $rootCats CategoryUtil::getCategoriesByRegistry($rootCatsIDs)
  1161.  
  1162.         if (empty($rootCats)) {
  1163.             return false;
  1164.         }
  1165.  
  1166.         // if the function was called to process the object categories
  1167.         if (isset($obj['__CATEGORIES__'])) {
  1168.             $ak array_keys($obj['__CATEGORIES__']);
  1169.             foreach ($ak as $prop{
  1170.                 CategoryUtil::buildRelativePathsForCategory ($rootCats[$prop]$obj['__CATEGORIES__'][$prop]$includeRoot);
  1171.             }
  1172.         // else, if the function was called to process the categories array directly
  1173.         else {
  1174.             $ak array_keys($obj);
  1175.             foreach ($ak as $prop{
  1176.                 CategoryUtil::buildRelativePathsForCategory ($rootCats[$prop]$obj[$prop]$includeRoot);
  1177.             }
  1178.         }
  1179.  
  1180.         return;
  1181.     }
  1182. }

Documentation generated on Fri, 18 Jul 2008 21:47:59 +0200 by phpDocumentor 1.4.1