ActionApps PHP Cross Reference Groupware Applications

Source: /central/include/actionapps.class.php - 755 lines - 31456 bytes - Summary - Text - Print

Description: File contains definition of AA_Actionapps class - holding information about one AA installation. Should be included to other scripts (as /admin/index.php3)

   1  <?php
   2  /**
   3   * File contains definition of AA_Actionapps class - holding information about
   4   * one AA installation.
   5   *
   6   * Should be included to other scripts (as /admin/index.php3)
   7   *
   8   * @version $Id: manager.class.php3 2323 2006-08-28 11:18:24Z honzam $
   9   * @author Honza Malik <honza.malik@ecn.cz>
  10   * @copyright Copyright (C) 1999, 2000 Association for Progressive Communications
  11  */
  12  /*
  13  Copyright (C) 1999, 2000 Association for Progressive Communications
  14  http://www.apc.org/
  15  
  16      This program is free software; you can redistribute it and/or modify
  17      it under the terms of the GNU General Public License as published by
  18      the Free Software Foundation; either version 2 of the License, or
  19      (at your option) any later version.
  20  
  21      This program is distributed in the hope that it will be useful,
  22      but WITHOUT ANY WARRANTY; without even the implied warranty of
  23      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24      GNU General Public License for more details.
  25  
  26      You should have received a copy of the GNU General Public License
  27      along with this program (LICENSE); if not, write to the Free Software
  28      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  29  */
  30  
  31  require_once  AA_INC_PATH. 'files.class.php3';
  32  
  33  /**
  34   * AA_Actionapps class - holds information about one AA installation
  35   */
  36  class AA_Actionapps {
  37  
  38      /** username of "access" user
  39       *  We use the access user acount to get informations about remote AA and
  40       *  to update the remote AA slices/setting. You should create such user on
  41       *  remote AA (superuser is enough :-)
  42       */
  43  
  44      /** local data (central_conf table) in ItemContent structure */
  45      var $local_data;
  46  
  47      /** cached remote session ID */
  48      var $_remote_session_id;
  49  
  50      /** time when we get remote session ID. We do not use sessions older than ...*/
  51      var $_remote_session_id_time;
  52  
  53      /** cached remote data - like AA name, ... */
  54      var $_cached;
  55  
  56      /** constructor - create AA_Actionapps object from ItemContent object
  57       *  grabbed from central_conf table.
  58       *  There are following fields:
  59       *    'id', 'dns_conf', 'dns_serial', 'dns_web', 'dns_mx', 'dns_db',
  60       *    'dns_prim', 'dns_sec', 'web_conf', 'web_path', 'db_server', 'db_name',
  61       *    'db_user', 'db_pwd', 'AA_SITE_PATH', 'AA_BASE_DIR', 'AA_HTTP_DOMAIN',
  62       *    'AA_ID', 'ORG_NAME', 'ERROR_REPORTING_EMAIL', 'ALERTS_EMAIL',
  63       *    'IMG_UPLOAD_MAX_SIZE', 'IMG_UPLOAD_URL', 'IMG_UPLOAD_PATH',
  64       *    'SCROLLER_LENGTH', 'FILEMAN_BASE_DIR', 'FILEMAN_BASE_URL',
  65       *    'FILEMAN_UPLOAD_TIME_LIMIT', 'AA_ADMIN_USER', 'AA_ADMIN_PWD',
  66       *    'status_code'));
  67       */
  68      function AA_Actionapps($content4id) {
  69          $this->local_data          = $content4id;
  70          $this->_remote_session_id  = null;
  71          $this->_remote_session_id_time  = 0;
  72          $this->_cached             = array();
  73      }
  74  
  75      /** getActionapps function
  76       *  static - main factory static method called like:
  77       *     $aa = AA_Actionapps::getActionapps($aa_id);
  78       * @param $aa_id
  79       */
  80      function & getActionapps($aa_id) {
  81          static $aas = array();
  82          if (!isset($aas[$aa_id])) {
  83              $aa_ic       = Central_GetAaContent(new zids($aa_id, 's'));
  84              $aas[$aa_id] = new AA_Actionapps(new ItemContent($aa_ic[$aa_id]));
  85          }
  86          return $aas[$aa_id];
  87      }
  88  
  89      /** url of remote AAs - like "http://example.org/apc-aa/"  */
  90      function getComunicatorUrl() {
  91          return Files::makeFile($this->getValue('AA_HTTP_DOMAIN'). $this->getValue('AA_BASE_DIR'), 'central/responder.php');
  92      }
  93  
  94      /** username of access user */
  95      function getAccessUsername() {
  96          return $this->getValue('AA_ADMIN_USER');
  97      }
  98  
  99      /** password of access user */
 100      function getAccessPassword() {
 101          return $this->getValue('AA_ADMIN_PWD');
 102      }
 103  
 104      /** get value from localy stored data (central_conf) */
 105      function getValue($field) {
 106          $ic = $this->local_data;
 107          return $ic->getValue($field);
 108      }
 109  
 110  
 111      /** name of AA as in local table*/
 112      function getName() {
 113          return $this->getValue('ORG_NAME'). ' ('. $this->getValue('AA_HTTP_DOMAIN'). $this->getValue('AA_BASE_DIR'). ')';
 114      }
 115  
 116      /** @return ORG_NAME of remote AAs
 117       *  Currently this function is not needed, since name of AA is pased
 118       *  by constructor (which is much quicker)
 119       */
 120      function requestAAName() {
 121          if ( is_null($this->_cached['org_name'])) {
 122              $response = $this->getResponse( new AA_Request('Get_Aaname') );
 123              if ($response->isError()) {
 124                  $this->_cached['org_name'] = _m("Can't get org_name - "). $response->getError();
 125              } else {
 126                  $response_arr = $response->getResponse();
 127                  $this->_cached['org_name'] = $response_arr['org_name'];
 128                  $this->_cached['domain']   = $response_arr['domain'];
 129              }
 130          }
 131          return $this->_cached['org_name'];
 132      }
 133  
 134  
 135      /** @return all slice names form remote AA
 136       *  mention, that the slices are identified by !name! not id for synchronization
 137       */
 138      function requestSlices() {
 139          return $this->requestModules(array('S'));
 140      }
 141  
 142      /** @return all module names form remote AA
 143       *  @param $types array of requested module types (A|Alerts|J|Lins|P|S|W)
 144       */
 145      function requestModules($types) {
 146          $response = $this->getResponse( new AA_Request('Get_Modules', array('types'=>$types)) );
 147          return ($response->isError()) ? array() : $response->getResponse();
 148      }
 149  
 150      /** @return structure which define all the definition of the slice
 151       *  (like slice properties, fields, views, ...). It is returned for all the
 152       *  slices in array
 153       */
 154      function requestDefinitions($type, $ids, $limited = array()) {
 155          // We will use rather one call which returns all the data for all the
 156          // slices, since it is much quicker than separate call for each slice
 157          $response = $this->getResponse( new AA_Request('Get_Module_Defs', array('type'=>$type, 'ids'=>$ids, 'limited'=>$limited)) );
 158          return ($response->isError()) ? array() : $response->getResponse();
 159      }
 160  
 161      /** This command synchronizes the slices base on sync[] array
 162       *  @return the report on the synchronization
 163       */
 164      function synchronize($sync_commands) {
 165          // We will use rather one call which returns all the data for all the
 166          // slices, since it is much quicker than separate call for each slice
 167          $response = $this->getResponse( new AA_Request('Do_Synchronize', array('sync'=>$sync_commands)) );
 168          return ($response->isError()) ? $response->getError() : $response->getResponse();
 169      }
 170  
 171      /** This command calls optimize method
 172       *  @return the report on the optimize
 173       */
 174      function doOptimize($optimize_class, $optimize_method) {
 175          $response = $this->getResponse( new AA_Request('Do_Optimize', array('class'=>$optimize_class, 'method'=>$optimize_method)) );
 176          return ($response->isError()) ? $response->getError() : $response->getResponse();
 177      }
 178  
 179      /** Imports slice to the current AA. The id of slice is the same as in
 180       *  definition
 181       */
 182      function importModuleChunk($definition_chunk) {
 183          // We will use rather one call which returns all the data for all the
 184          // slices, since it is much quicker than separate call for each slice
 185  
 186          $response = $this->getResponse( new AA_Request('Do_Import_Module_Chunk', array('definition_chunk'=>$definition_chunk)) );
 187          return ($response->isError()) ? $response->getError() : $response->getResponse();
 188      }
 189  
 190      /** Main communication function - returns AA_Response object */
 191      function getResponse($request) {
 192          if ( !$this->_remote_session_id OR $this->_remote_session_id_time < (now() - 10*60)) {  // 10 minutes
 193              $response = $this->_authenticate();
 194              if ($response->isError()) {
 195                  return $response;
 196              }
 197          }
 198          // _remote_session_id is set
 199          return $request->ask($this->getComunicatorUrl(), array('AA_CP_Session'=>$this->_remote_session_id));
 200      }
 201  
 202      function _authenticate() {
 203          $request  = new AA_Request('Get_Sessionid');
 204          $response = $request->ask($this->getComunicatorUrl(), array('free' => $this->getAccessUsername(), 'freepwd' =>$this->getAccessPassword()));
 205          if ( !$response->isError() ) {
 206              $this->_remote_session_id = $response->getResponse();
 207              $this->_remote_session_id_time = now();
 208          }
 209          return $response;
 210      }
 211  
 212      /// Static methods
 213      /** create array of all Approved AAs from central database */
 214      function getArray() {
 215  
 216          $ret    = array();
 217          $conds  = array();
 218          $sort[] = array('ORG_NAME' => 'a');
 219          $zids   = Central_QueryZids($conds, $sort, AA_BIN_APPROVED);
 220          $aa_ic  = Central_GetAaContent($zids);
 221  
 222          foreach ($aa_ic as $k => $content4id) {
 223              $ret[$k] = new AA_Actionapps(new ItemContent($content4id));
 224          }
 225          return $ret;
 226      }
 227  }
 228  
 229  
 230  class AA_Module_Definition {
 231      /** module id is unpacked */
 232      var $module_id;
 233      /** data for the module */
 234      var $data;
 235  
 236      function AA_Module_Definition() {
 237          $this->clear();
 238      }
 239  
 240      function clear() {
 241          $this->module_id = null;
 242          $this->data      = array();
 243      }
 244  
 245      function loadForId($module_id, $limited=false) {
 246          $this->module_id = $module_id;
 247          $this->clear();
 248          // should be overloaded in childs
 249      }
 250  
 251      function getArray() {
 252          return $this->data;
 253      }
 254  
 255      function getId() {
 256          return $this->module_id;
 257      }
 258  
 259      /** returns module name */
 260      function getName() {
 261          return $this->data['module']['name'];
 262      }
 263  
 264      function compareWith($dest_def) {
 265          // should be overloaded in childs
 266      }
 267  
 268      function planModuleImport($aa) {
 269          $no_sync_tasks = 0;
 270          $toexecute = new AA_Toexecute;
 271  
 272          foreach ($this->data as $table => $rows) {
 273              $chunks = AA_Module_Definition_Chunk::factoryArray($this->module_id, $table, $rows);
 274              foreach ($chunks as $chunk) {
 275                  $import_task = new AA_Task_Import_Module_Chunk($chunk, $aa);
 276                  $toexecute->userQueue($import_task, array(), 'AA_Task_Import_Module_Chunk');
 277              }
 278              $no_sync_tasks += count($chunks);
 279          }
 280          return $no_sync_tasks;
 281      }
 282  }
 283  
 284  /** AA_Module_Definition could be splited to more pieces (chunks) for easier
 285   *  transmission and import
 286   */
 287  class AA_Module_Definition_Chunk {
 288  
 289      /** module id is unpacked */
 290      var $module_id;
 291      /** part of the data for the module definition */
 292      var $data;
 293  
 294      /** Creates array of chunks from given data. The data are splited to more
 295       *  chunks, if it is bigger than limit.
 296       *  static class member method
 297       **/
 298      function factoryArray($module_id, $table, $rows) {
 299          $chunks = array();
 300  
 301          // maximum 1000 rows in one chunk
 302          $chunks_data = array_chunk($rows, 1000, true);
 303          foreach ($chunks_data as $chunk_data) {
 304              $chunks[] = new AA_Module_Definition_Chunk($module_id, $table, $chunk_data);
 305          }
 306          return $chunks;
 307      }
 308  
 309      function AA_Module_Definition_Chunk($module_id, $table, $rows) {
 310          $this->module_id = $module_id;
 311          $this->data      = array($table => $rows);
 312      }
 313  
 314      function importModuleChunk() {
 315  
 316          $metabase    = AA_Metabase::singleton();
 317  
 318          foreach ($this->data as $table => $records) {
 319              if ( empty($records) ) {
 320                  continue;
 321              }
 322  
 323              $metabase->packIds($table, $records);    // pack ids ...
 324              foreach ($records as $data) {
 325                  $metabase->doInsert($table, $data, 'nohalt');
 326              }
 327          }
 328          return 'ok';
 329      }
 330  }
 331  
 332  class AA_Module_Definition_Slice extends AA_Module_Definition {
 333  
 334      function loadForId($module_id, $limited=array()) {
 335          $this->clear();
 336          $this->module_id = $module_id;
 337          $metabase        = AA_Metabase::singleton();
 338  
 339          if ($limited['definitions']) {
 340              $this->data['module']       = $metabase->getModuleRows('module',      $module_id);
 341              $this->data['slice']        = $metabase->getModuleRows('slice',       $module_id);
 342              $this->data['field']        = $metabase->getModuleRows('field',       $module_id);
 343              $this->data['view']         = $metabase->getModuleRows('view',        $module_id);
 344              $this->data['email']        = $metabase->getModuleRows('email',       $module_id);
 345              $this->data['email_notify'] = $metabase->getModuleRows('email_notify',$module_id);
 346              $this->data['profile']      = $metabase->getModuleRows('profile',     $module_id);
 347              $this->data['rssfeeds']     = $metabase->getModuleRows('rssfeeds',    $module_id);
 348  
 349              // @todo - do it better - check the fields setting, and get all the constants used
 350              $this->data['constant_slice'] = $metabase->getModuleRows('constant_slice', $module_id);
 351              $this->data['constant']       = $metabase->getModuleRows('constant', $module_id);
 352              if (is_array($this->data['constant'])) {
 353                  $constant_groups = array();
 354                  foreach ($this->data['constant'] as $k => $v) {
 355                      $constant_groups[$v['group_id']] = true;   // get list of all groups
 356                  }
 357  
 358                  $SQL = "SELECT * FROM constant WHERE group_id='lt_groupNames' AND ". Cvarset::sqlin('value', array_keys($constant_groups));
 359  
 360                  $groups = GetTable2Array($SQL, "unpack:id", 'aa_fields');
 361                  if (!is_array($groups)) {
 362                      $groups = array();
 363                  }
 364                  foreach ($groups as $k => $v) {
 365                      $groups[$k]['id'] = unpack_id($v['id']);
 366                  }
 367                  $this->data['constant'] = array_merge($this->data['constant'], $groups);
 368              }
 369          }
 370  
 371          if ( $limited['items']) {
 372              $this->data['item']       = $metabase->getModuleRows('item'      , $module_id);
 373              $this->data['content']    = $metabase->getModuleRows('content'   , $module_id);
 374              $this->data['discussion'] = $metabase->getModuleRows('discussion', $module_id);
 375          }
 376      }
 377  
 378      function compareWith($dest_def) {
 379          /** @todo check the state, when the name contains "->" */
 380          $dest_module_id = $dest_def->getId();
 381          $metabase       = AA_Metabase::singleton();
 382  
 383          $diff =                    AA_Difference::_compareArray(reset($this->data['module']),  reset($dest_def->data['module']), new AA_Identifier($dest_module_id, 'module', $dest_module_id), array($metabase->getModuleField('module'))); // just module data
 384          $diff = array_merge($diff, AA_Difference::_compareArray(reset($this->data['slice']),   reset($dest_def->data['slice']),  new AA_Identifier($dest_module_id, 'slice', $dest_module_id),  array($metabase->getModuleField('slice'))));  // just slice data
 385          $diff = array_merge($diff, AA_Difference::_compareArray($this->data['field'],    $dest_def->data['field'],    new AA_Identifier($dest_module_id, 'field'),    array($metabase->getModuleField('field'))));
 386          $diff = array_merge($diff, AA_Difference::_compareArray($this->data['view'],     $dest_def->data['view'],     new AA_Identifier($dest_module_id, 'view'),     array($metabase->getModuleField('view'))));
 387          $diff = array_merge($diff, AA_Difference::_compareArray($this->data['email'],    $dest_def->data['email'],    new AA_Identifier($dest_module_id, 'email'),    array($metabase->getModuleField('email'))));
 388          $diff = array_merge($diff, AA_Difference::_compareArray($this->data['constant_slice'], $dest_def->data['constant_slice'], new AA_Identifier($dest_module_id, 'constant_slice'), array($metabase->getModuleField('constant_slice'))));
 389          $diff = array_merge($diff, AA_Difference::_compareArray($this->data['constant'], $dest_def->data['constant'], new AA_Identifier($dest_module_id, 'constant'), array($metabase->getModuleField('constant'))));
 390          return $diff;
 391      }
 392  }
 393  
 394  class AA_Module_Definition_Site extends AA_Module_Definition {
 395  
 396      function loadForId($module_id, $limited=false) {
 397          $this->clear();
 398          $this->module_id = $module_id;
 399          $metabase        = AA_Metabase::singleton();
 400  
 401          $this->data['module']    = $metabase->getModuleRows('module', $module_id);
 402          $this->data['site']      = $metabase->getModuleRows('site', $module_id);
 403          $this->data['site_spot'] = $metabase->getModuleRows('site_spot', $module_id);
 404      }
 405  
 406      function compareWith($dest_def) {
 407      }
 408  }
 409  
 410  class AA_Module_Definition_Alerts extends AA_Module_Definition {
 411  
 412      function loadForId($module_id, $limited=false) {
 413          $this->clear();
 414          $this->module_id = $module_id;
 415          $metabase        = AA_Metabase::singleton();
 416  
 417          $this->data['module']                     = $metabase->getModuleRows('module', $module_id);
 418          $this->data['alerts_collection']          = $metabase->getModuleRows('alerts_collection', $module_id);
 419          $this->data['alerts_collection_filter']   = $metabase->getModuleRows('alerts_collection_filter', $module_id);
 420          $this->data['alerts_collection_howoften'] = $metabase->getModuleRows('alerts_collection_howoften', $module_id);
 421         // @todo - filter is not copied since it need double jopined tabled in metabase's  getModuleRows()
 422         // $this->data['alerts_filter']              = $metabase->getModuleRows('alerts_filter', $module_id);
 423      }
 424  
 425      function compareWith($dest_def) {
 426      }
 427  }
 428  
 429  
 430  class AA_Difference {
 431  
 432      var $description;
 433      var $type;           // INFO | DIFFERENT_ROW | DIFFERENT_VALUE | NEW | DELETED
 434      /** array of AA_Sync_Actions defining, what we can do with this difference */
 435      var $actions;
 436  
 437      /** */
 438      function AA_Difference($type, $description, $actions=array()) {
 439          $this->type        = $type;
 440          $this->description = $description;
 441          $this->actions     = empty($actions) ? array() : (is_array($actions) ? $actions : array($actions));
 442      }
 443  
 444      function printOut() {
 445          echo "\n<tr class=\"diff_".strtolower($this->type)."\"><td>". $this->description .'</td><td>';
 446          foreach ($this->actions as $action) {
 447              $action->printToForm();
 448          }
 449          echo '</td></tr>';
 450      }
 451  
 452      /// Static
 453  
 454      function _compareArray($template_arr, $destination_arr, $identifier, $ignore) {
 455          $diff       = array();
 456          if (! is_array($template_arr) AND is_array($destination_arr)) {
 457              return array( 0 => new AA_Difference('DELETED', _m('%1 is not array in template slice', array($identifier->toString())), new AA_Sync_Action('DELETE', $identifier)));
 458          }
 459          if ( is_array($template_arr) AND !is_array($destination_arr)) {
 460              return array( 0 => new AA_Difference('NEW', _m('%1 is not array in destination slice', array($identifier->toString())), new AA_Sync_Action('INSERT', $identifier, $template_arr)));
 461          }
 462          if ( !is_array($template_arr) AND !is_array($destination_arr)) {
 463              return array( 0 => new AA_Difference('INFO', _m('%1 is not defined for both AAs', array($identifier->toString()))));
 464          }
 465  
 466          // if we comparing row values, we can also update whole row at once - so we mark it
 467          $is_different = false;
 468          foreach ($template_arr as $key => $value) {
 469              $sub_identifier = clone($identifier);
 470              $sub_identifier->sub($key);
 471  
 472              // some fields we do not want to compare (like slice_ids)
 473              if (in_array($key, $ignore)) {
 474                  // we need to clear the destination array in order we can know,
 475                  // that there are some additional keys in it (compated to template)
 476                  unset($destination_arr[$key]);
 477                  continue;
 478              }
 479              if (is_array($value)) {
 480                  $diff = array_merge($diff, AA_Difference::_compareArray($value, $destination_arr[$key], $sub_identifier, $ignore));
 481                  // we need to clear the destination array in order we can know,
 482                  // that there are some additional keys in it (compated to template)
 483                  unset($destination_arr[$key]);
 484              }
 485              elseif (!array_key_exists($key,$destination_arr)) {
 486                  $diff[] = new AA_Difference('DIFFERENT_VALUE', '&nbsp;&nbsp;&nbsp;-&nbsp;'. _m('There is no such key (%1) in destination slice for %2', array($key, $identifier->toString())), new AA_Sync_Action('UPDATE_VALUE', $sub_identifier, $value));
 487              }
 488              elseif (($value != $destination_arr[$key]) AND !(empty($value) AND empty($destination_arr[$key]))) {  // '' and 0 is considered equal
 489                 // if we comparing row values, we can also update whole row at once - so we mark it
 490                 $is_different = true;
 491  
 492                 $code = '{htmltoggle:&gt;&gt;::&lt;&lt;:'. AA_Stringexpand::quoteColons('
 493                         <div style="background-color:#FFE0E0;border: solid 1px #F88;">'._m('Destination').':<br>'.safe($destination_arr[$key]).'</div>
 494                         <br>
 495                         <div style="background-color:#E0E0FF;border: solid 1px #88F;">'._m('Template').':<br>'.safe($value).'</div>'). '}';
 496                  $diff[] = new AA_Difference('DIFFERENT_VALUE', '&nbsp;&nbsp;&nbsp;-&nbsp;'. _m('The value for key %1 in %2 array is different %3', array($key, $identifier->toString(), AA_Stringexpand::unalias($code))), new AA_Sync_Action('UPDATE_VALUE', $sub_identifier, $value));
 497                  // we need to clear the destination array in order we can know,
 498                  // that there are some additional keys in it (compated to template)
 499                  unset($destination_arr[$key]);
 500              } else {
 501                  unset($destination_arr[$key]);
 502              }
 503          }
 504          if ($is_different) {
 505              array_unshift($diff, new AA_Difference('DIFFERENT_ROW', _m('The record for %1 is different', array($identifier->toString())), new AA_Sync_Action('UPDATE_ROW', $identifier, $template_arr)));
 506          }
 507  
 508          foreach ($destination_arr as $key => $value) {
 509              $sub_identifier = clone($identifier);
 510              $sub_identifier->sub($key);
 511  
 512              // there are no such keys in template
 513              if ( is_array($value) ) {
 514                  // I know - we can define the difference right here, but it is better to use the same method as above
 515                  $diff = array_merge($diff, AA_Difference::_compareArray('',$destination_arr[$key], $sub_identifier, $ignore));
 516              } else {
 517                  $diff[] = new AA_Difference('DELETED', '&nbsp;&nbsp;&nbsp;-&nbsp;'. _m('There is no such key (%1) in template slice for %2', array($key, $sub_identifier->toString())), new AA_Sync_Action('UPDATE_VALUE', $sub_identifier, ''));
 518              }
 519          }
 520          if ( count($diff) < 1 ) {
 521              $diff[] = new AA_Difference('INFO', _m('%1 are identical', array($identifier->toString())));
 522          }
 523          return $diff;
 524      }
 525  }
 526  
 527  class AA_Identifier {
 528  
 529      /**  $path[0] ~ module_id, [1] ~ table, [2] ~ row, [3] ~ column */
 530      var $path;
 531  
 532      function AA_Identifier($module_id=null, $table=null, $row=null, $column=null) {
 533          $this->path = array();
 534          if ($module_id) {
 535              $this->path[0] = $module_id;
 536              if ($table) {
 537                  $this->path[1] = $table;
 538                  if ($row) {
 539                      $this->path[2] = $row;
 540                      if ($column) {
 541                          $this->path[3] = $column;
 542                      }
 543                  }
 544              }
 545          }
 546      }
 547  
 548      function getModuleId() { return $this->path[0]; }
 549      function getTable()    { return $this->path[1]; }
 550      function getRow()      { return $this->path[2]; }
 551      function getColumn()   { return $this->path[3]; }
 552  
 553      /** Parses the identifier string (like "Configuración->field->category........")
 554       *  static member function - called like $idf = AA_Identifier::factoryFromString($idf_string)
 555       */
 556      function factoryFromString($idf) {
 557          list($module_id, $table, $row, $column) = explode('->', $idf);
 558          return new AA_Identifier($module_id, $table, $row, $column);
 559      }
 560  
 561      /** creates identifier which identifies one part of the current idenftifier
 562       *  say '534633'->view->32  ---> .sub('name') ---> '534633'->view->32->name
 563       */
 564      function sub($sub_id) {
 565          $this->path[] = $sub_id;
 566          return;
 567      }
 568  
 569      function toString() {
 570          return join('->',$this->path);
 571      }
 572  }
 573  
 574  /** Class which defines synchronization actions */
 575  class AA_Sync_Action {
 576      /** action type  - DELETE | INSERT | UPDATE_ROW | UPDATE_VALUE */
 577      var $type;
 578  
 579      /** AA_Identifier object holding something like 'My Slice->view->678->name' */
 580      var $identifier;
 581  
 582      /** action parameters (field's data). Could be scalar as well as array */
 583      var $params;
 584  
 585      function AA_Sync_Action($type, $identifier, $params=null) {
 586          $this->type       = $type;
 587          $this->identifier = $identifier;
 588          $this->params     = $params;
 589      }
 590  
 591      function printToForm() {
 592          $packed_action = serialize($this);
 593          echo '<div>';
 594          $state = isset($_POST['sync']) ? in_array($packed_action, (array)$_POST['sync']) : ($this->type != 'UPDATE_VALUE');
 595          FrmChBoxEasy('sync[]', $state, '', $packed_action);
 596          switch ( $this->type ) {
 597              case 'DELETE': echo _m("Delete"); break;
 598              case 'INSERT': echo _m("Create new"); break;
 599              case 'UPDATE_ROW':
 600              case 'UPDATE_VALUE': echo _m("Update"); break;
 601          }
 602          echo '</div>';
 603      }
 604  
 605      /** returns data array as we need it for $metabase->doInsert/Update */
 606      function _getDataArray() {
 607          $idf    = $this->identifier;
 608          $column = $idf->getColumn();
 609          return $column ? array( $column => $this->params) : $this->params;
 610      }
 611  
 612      /** do synchronization action in destination slice */
 613      function doAction() {
 614  
 615          // commands are stored as tree - like:
 616          // 6353636737->field->category........
 617          // 6353636737 is id of slice - we use slice name as identifier
 618          // here, because slice_id is different in remote slices and we want
 619          // to synchronize the slices of the same name
 620          $idf         = $this->identifier;
 621          $module_id   = $idf->getModuleId();
 622          $table       = $idf->getTable();
 623          $row         = $idf->getRow();
 624          $column      = $idf->getColumn();
 625  
 626          $p_module_id = pack_id($module_id);
 627  
 628          $metabase    = AA_Metabase::singleton();
 629  
 630          if (!$row) {
 631              return _m('Wrong command - row is not defined - %1', array($idf->toString()));
 632          }
 633          if ( ($this->type == 'UPDATE_ROW') OR ($this->type == 'UPDATE_VALUE') ) {
 634              $data = $this->_getDataArray();
 635              $metabase->fillKeys($data, $idf);
 636              $metabase->doUpdate($table, $data);
 637              return _m('%1 %2 in slice %3 updated', array($table, $row, $module_id));
 638          }
 639          if ( $this->type == 'INSERT' ) {
 640              $data = $this->params;
 641              $metabase->fillKeys($data, $idf);
 642              $metabase->doInsert($table, $data);
 643              return _m('%1 %2 inserted into slice %3', array($table, $row, $module_id));  // field xy inserted into slice yz
 644          }
 645          if ( $this->type == 'DELETE' ) {
 646              $data = array();
 647              $metabase->fillKeys($data, $idf);
 648              $metabase->doDelete($table, $data);
 649              return _m('%1 %2 deleted from slice %3', array($table, $row, $module_id));
 650          }
 651          return _m("Unknown action (%1) for field %2 in slice %3", array($this->type, $row, $module_id));
 652      }
 653  }
 654  
 655  
 656  /** Stores the synchronization action which should be performed on remote AA
 657   *  Objects are stored into AA_Toexecute queue for running from Task Manager
 658   **/
 659  class AA_Task_Sync {
 660      /** AA_Sync_Action object - Action to do */
 661      var $sync_action;
 662  
 663      /** AA_Actionapps object  - In which AA we have to do the action */
 664      var $actionapps;
 665  
 666      function AA_Task_Sync($sync_action, $actionapps) {
 667          $this->sync_action = $sync_action;
 668          $this->actionapps  = $actionapps;
 669      }
 670  
 671      function toexecutelater() {
 672          // synchronize accepts array of sync_actions, so it is possible
 673          // to do more action by one call
 674          return $this->actionapps->synchronize(array($this->sync_action));
 675      }
 676  }
 677  
 678  /** Stores the synchronization action which should be performed on remote AA
 679   *  Objects are stored into AA_Toexecute queue for running from Task Manager
 680   **/
 681  class AA_Task_Import_Module_Chunk {
 682      /** AA_Module_Definition_* object for import */
 683      var $module_definition_chunk;
 684  
 685      /** AA_Actionapps object  - In which AA we have to do the action */
 686      var $actionapps;
 687  
 688      function AA_Task_Import_Module_Chunk($module_definition_chunk, $actionapps) {
 689          $this->module_definition_chunk = $module_definition_chunk;
 690          $this->actionapps              = $actionapps;
 691      }
 692  
 693      function toexecutelater() {
 694          // synchronize accepts array of sync_actions, so it is possible
 695          // to do more action by one call
 696          return $this->actionapps->importModuleChunk($this->module_definition_chunk);
 697      }
 698  }
 699  
 700  
 701  /** Central_GetAaContent function for loading content of AA configuration
 702   *  for manager class
 703   *
 704   * Loads data from database for given AA ids (called in itemview class)
 705   * and stores it in the 'Abstract Data Structure' for use with 'item' class
 706   *
 707   * @see GetItemContent(), itemview class, item class
 708   * @param array $zids array if ids to get from database
 709   * @return array - Abstract Data Structure containing the links data
 710   *                 {@link http://apc-aa.sourceforge.net/faq/#1337}
 711   */
 712  function Central_GetAaContent($zids) {
 713      $content = array();
 714      $ret     = array();
 715  
 716      // construct WHERE clausule
 717      $sel_in = $zids->sqlin( false );
 718      $SQL = "SELECT * FROM central_conf WHERE id $sel_in";
 719      StoreTable2Content($content, $SQL, '', 'id');
 720      // it is unordered, so we have to sort it:
 721      for($i=0; $i<$zids->count(); $i++ ) {
 722          $ret[(string)$zids->id($i)] = $content[$zids->id($i)];
 723      }
 724      return $ret;
 725  }
 726  
 727  /** Central_QueryZids - Finds link IDs for links according to given  conditions
 728   *  @param array  $conds    - search conditions (see FAQ)
 729   *  @param array  $sort     - sort fields (see FAQ)
 730   *  @param string $type     - bins as known from items
 731   *       AA_BIN_ACTIVE | AA_BIN_HOLDING | AA_BIN_TRASH | AA_BIN_ALL
 732   *  @global int  $QueryIDsCount - set to the count of IDs returned
 733   *  @global bool $debug=1       - many debug messages
 734   *  @global bool $nocache       - do not use cache, even if use_cache is set
 735   */
 736  function Central_QueryZids($conds, $sort="", $type="app") {
 737      global $debug;                 // displays debug messages
 738      global $nocache;               // do not use cache, if set
 739  
 740      if ( $debug ) huhl( "<br>Conds:", $conds, "<br>--<br>Sort:", $sort, "<br>--");
 741  
 742      $metabase    = AA_Metabase::singleton();
 743  
 744      $fields      = $metabase->getSearchArray('central_conf');
 745      $join_tables = array();   // not used in this function
 746  
 747      $SQL  = 'SELECT DISTINCT id FROM central_conf WHERE ';
 748      $SQL .= CreateBinCondition($type, 'central_conf');
 749      $SQL .= MakeSQLConditions($fields, $conds, $fields, $join_tables);
 750      $SQL .= MakeSQLOrderBy($fields, $sort, $join_tables);
 751  
 752      return GetZidsFromSQL($SQL, 'id');
 753  }
 754  
 755  ?>

title

Description

title

Description

title

Description

title

title

Body