Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
funnelback_manager.inc
1 <?php
18 require_once SQ_INCLUDE_PATH.'/asset.inc';
19 
32 {
33 
34 
41  function __construct($assetid=0)
42  {
43  $this->_ser_attrs = TRUE;
44  parent::__construct($assetid);
45 
46  }//end constructor
47 
48 
58  function create(Array &$link)
59  {
60  require_once SQ_CORE_PACKAGE_PATH.'/system/system_asset_fns.inc';
61  if (!system_asset_fns_create_pre_check($this)) {
62  return FALSE;
63  }
64  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
65  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
66 
67  if ($linkid = parent::create($link)) {
68  if (!system_asset_fns_create_cleanup($this)) {
69  $linkid = FALSE;
70  }
71  }
72 
73  if ($linkid) {
74  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
75  } else {
76  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
77  }
78 
79  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
80  return $linkid;
81 
82  }//end create()
83 
84 
94  function _getName($short_name=FALSE)
95  {
96  return $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->type(), 'name');
97 
98  }//end _getName()
99 
100 
107  function canDelete()
108  {
109  return FALSE;
110 
111  }//end canDelete()
112 
113 
120  function canClone()
121  {
122  return FALSE;
123 
124  }//end canClone()
125 
126 
127 //-- EVENT STUBS --//
128 
129 
140  function onAssetUpdate(&$broadcaster, $vars=Array())
141  {
142  if (!$this->attr('indexing')) return FALSE;
143  $vars['action'] = 'update';
144  $this->updateAsset($broadcaster, $vars);
145 
146  return TRUE;
147 
148  }//end onAssetUpdate()
149 
150 
161  function onAssetStatusUpdate(&$broadcaster, $vars=Array())
162  {
163  if (!$this->attr('indexing')) return FALSE;
164  $vars['action'] = 'status_update';
165  $this->updateAsset($broadcaster, $vars);
166 
167  return TRUE;
168 
169  }//end onAssetStatusUpdate()
170 
171 
181  function onAttributeChange(&$broadcaster, $vars=Array())
182  {
183  if (!$this->attr('indexing')) return FALSE;
184  $vars['action'] = 'update';
185  $this->updateAsset($broadcaster, $vars);
186 
187  return TRUE;
188 
189  }//end onAttributeChange()
190 
191 
202  function onContentsUpdated(&$broadcaster, $vars=Array())
203  {
204  if (!$this->attr('indexing')) return FALSE;
205  $vars['action'] = 'update';
206  $this->updateAsset($broadcaster, $vars);
207 
208  return TRUE;
209 
210  }//end onContentsUpdated()
211 
212 
223  function onAssetDeleted(&$broadcaster, $vars=Array())
224  {
225  if (!$this->attr('indexing')) return FALSE;
226  $vars['action'] = 'delete';
227  $this->updateAsset($broadcaster, $vars);
228 
229  return TRUE;
230 
231  }//end onAssetDeleted()
232 
233 
244  function onPermissionChange(&$broadcaster, $vars=Array())
245  {
246  if (!$this->attr('indexing')) return FALSE;
247  $vars['action'] = 'permission_change';
248  $this->updateAsset($broadcaster, $vars);
249 
250  return TRUE;
251 
252  }//end onPermissionChange()
253 
254 
265  function onLookupsUpdated(&$broadcaster, $vars=Array())
266  {
267  if (!$this->attr('indexing')) return FALSE;
268  $vars['action'] = 'lookups_updated';
269  $this->updateAsset($broadcaster, $vars);
270 
271  return TRUE;
272 
273  }//end onLookupsUpdated()
274 
275 
286  function onMetadataDeleted(&$broadcaster, $vars=Array())
287  {
288  if (!$this->attr('indexing')) return FALSE;
289  $vars['action'] = 'metadata_delete';
290  $this->updateAsset($broadcaster, $vars);
291 
292  return TRUE;
293 
294  }//end onMetadataDeleted()
295 
296 
307  function onMetadataUpdate(&$broadcaster, $vars=Array())
308  {
309  if (!$this->attr('indexing')) return FALSE;
310  $vars['action'] = 'metadata_update';
311  $this->updateAsset($broadcaster, $vars);
312 
313  return TRUE;
314 
315  }//end onMetadataUpdate()
316 
317 
318 // --- ASSET UPDATE --- //
319 
320 
330  public function updateAsset(&$asset, $vars=Array())
331  {
332  // if funnelback manager is updated then there is infinite recursion!!!
333  if ($asset->id == $this->id) return FALSE;
334 
335  // We don't need to update the xml while we are creating a new asset.
336  // This will stop the xml getting regenerated while
337  // permissions, metadata, workflow are being applied.
338  if (isset($asset->_tmp['__creating__']) && $asset->_tmp['__creating__'] === TRUE) return FALSE;
339 
340  // We need the URL, if the asset has no url, bail early.
341  $urls = $asset->getURLs();
342  if (empty($urls)) {
343  return $this->_cleanupEntriesByAssetid($asset->id);
344  }
345 
346  $action = array_get_index($vars, 'action', '');
347 
348  // If the action is delete, just delete and do not worry about the rest
349  if ($action == 'delete') {
350  return $this->_cleanupEntriesByAssetid($asset->id);
351  }//end if
352 
353  // Exclusions
354  $exclusions = $this->attr('global_exclude');
355  $excluded_assets = array_get_index($exclusions, 'assetid', Array());
356  $excluded_types = array_get_index($exclusions, 'type', Array());
357  $excluded_nodes = array_get_index($exclusions, 'tree', Array());
358  $asset_type = $asset->type();
359 
360  // Exclude By Assetid
361  if (in_array($asset->id, $excluded_assets)) {
362  return $this->_cleanupEntriesByAssetid($asset->id);
363  }//end if
364 
365  // Exclude By Type
366  if (in_array($asset_type, $excluded_types)) {
367  return $this->_cleanupEntriesByAssetid($asset->id);
368  }//end if
369 
370  // Exclude By Root Node
371  if (!empty($excluded_nodes)) {
372  if ($GLOBALS['SQ_SYSTEM']->am->isUnderRootNodes($asset->id, $excluded_nodes)) {
373  return $this->_cleanupEntriesByAssetid($asset->id);
374  }
375  }//end if
376 
377  // Geeez, if the action is a status change, we *need* to hack the status, otherwise it doesn't register
378  // This is because the status at this point, hasn't gone through a status change yet.
379  $new_status = array_get_index($vars, 'new_status', 0);
380  $old_status = array_get_index($vars, 'old_status', 0);
381  if ($action == 'status_update' && $new_status != $asset->status && $new_status != $old_status) {
382  $asset_status = $new_status;
383  } else {
384  $asset_status = $asset->status;
385  }//end if
386 
387  $public_user = $GLOBALS['SQ_SYSTEM']->am->getSystemAssetid('public_user');
388  $live = (!($asset_status & SQ_SC_STATUS_NOT_LIVE) && $asset->readAccess(Array($public_user)));
389  $lookups = $asset->getLookups();
390 
391  // Delete first, ask questions later...
392  if ($this->_cleanupEntriesByAssetid($asset->id)) {
393  // get a placeholder for the url.
394  // it'll be filled in down the line.
395  $url_template = $this->_generateXML('%%sq_temp_fb_url%%', $asset);
396 
397  // Create a list of urls per root url id.
398  // We do this once to save having to loop over it below.
399  // Should save some time if a system has a lot of urls applied
400  // to a site.
401  $root_urls = array();
402  foreach ($lookups as $lookup) {
403  $lookup_url = array_get_index($lookup, 'url', '');
404  $root_urlid = array_get_index($lookup, 'root_urlid', FALSE);
405  if ($root_urlid === FALSE) continue;
406  if (empty($lookup_url)) continue;
407  $root_urls[$lookup_url] = $root_urlid;
408  }//end foreach
409 
410  // Now go through each url, adding the correct entries back in, with the correct xml
411  foreach ($urls as $url_info) {
412  // This should *never* happen
413  if (empty($url_info['url'])) continue;
414 
415  // Find the root url
416  if (array_key_exists($url_info['url'], $root_urls) === TRUE) {
417  $root_urlid = $root_urls[$url_info['url']];
418  } else {
419  continue;
420  }
421 
422  // Compile the URLs
423  $http_url = (($url_info['http']) ? 'http://'.$url_info['url'] : '');
424  $https_url = (($url_info['https']) ? 'https://'.$url_info['url'] : '');
425 
426  $all_site_urls = $this->_getSiteURL($root_urlid, $asset, $url_info['url']);
427 
428  // HTTP Url found, add entry
429  if (!empty($http_url)) {
430  $sitemap_url = str_replace('&#039;', '&apos;', htmlspecialchars($http_url, ENT_QUOTES, SQ_CONF_DEFAULT_CHARACTER_SET));
431  $sitemap_xml = str_replace('%%sq_temp_fb_url%%', $sitemap_url, $url_template);
432  if (!empty($sitemap_xml)) {
433  foreach ($all_site_urls as $site_url) {
434  if(strpos($http_url,'__data') !== FALSE) {
435  $original_urls = $asset->getOriginalURL($http_url, $site_url);
436  } else {
437  $original_urls = Array($http_url);
438  }
439  foreach($original_urls as $original_url) {
440  if (strpos($site_url, 'http:') === 0) {
441  $this->_addEntry($http_url, $asset->id, $site_url, $root_urlid, $live, $sitemap_xml, $original_url);
442  }//end if
443  }
444  }//end foreach
445  }//end if
446  }//end if
447 
448  // HTTPS Url found, add entry
449  if (!empty($https_url)) {
450  $sitemap_url = str_replace('&#039;', '&apos;', htmlspecialchars($https_url, ENT_QUOTES, SQ_CONF_DEFAULT_CHARACTER_SET));
451  $sitemap_xml = str_replace('%%sq_temp_fb_url%%', $sitemap_url, $url_template);
452  if (!empty($sitemap_xml)) {
453  foreach ($all_site_urls as $site_url) {
454  if(strpos($https_url,'__data') !== FALSE) {
455  $original_urls = $asset->getOriginalURL($https_url, $site_url);
456  } else {
457  $original_urls = Array($https_url);
458  }
459  foreach($original_urls as $original_url) {
460  if (strpos($site_url, 'https:') === 0) {
461  $this->_addEntry($https_url, $asset->id, $site_url, $root_urlid, $live, $sitemap_xml, $original_url);
462  }//end if
463  }
464  }//end foreach
465  }//end if
466  }//end if
467  }//end foreach
468  } else {
469  // Failed to delete
470  return FALSE;
471  }//end if
472 
473  return TRUE;
474 
475  }//end updateAsset()
476 
477 
478 // --- SITE MAP CACHING FUNCTIONS --- //
479 
480 
493  public function _generateXML($url, $asset)
494  {
495  // No asset? Why even bother?
496  if (is_null($asset)) {
497  return '';
498  }//end if
499 
500  // Some definitions
501  $mm = $GLOBALS['SQ_SYSTEM']->getMetadataManager();
502 
503  $xml = '<url>';
504  $xml .= '<loc>'.$url.'</loc>';
505  $xml .= '<lastmod>'.date('Y-m-d', $asset->updated).'T'.date('H:i:s', $asset->updated).'</lastmod>';
506 
507  $access_locks = $this->getAccessLocks($asset);
508  if (!empty($access_locks)) {
509  $xml .= '<fbmeta name="access_locks" content="'.$access_locks.'" />';
510  }
511  // Add in the metadata
512  // get schemas first using just getMetadata() but it wont get us the default value on the asset
513  // which is not good enough for us so get the default values later again and merge it
514  $metadata = $mm->getMetadata($asset->id);
515 
516  // now the default values
517  $schemas_applied = $mm->getSchemas($asset->id, TRUE);
518  $default_values = Array();
519  foreach($schemas_applied as $schemaid) {
520  $defaults = $mm->getSchemaDefaultValues($schemaid);
521  // get the correct format of the array
522  foreach ($defaults as $field_id => $field_info) {
523  if(isset($metadata[$field_id])) continue;
524  $metadata[$field_id][0] = $field_info;
525  }
526  }
527 
528  foreach ($metadata as $info) {
529  $name = $info[0]['name'];
530 
531  // Fall back, if a metadata field is name "access_locks", it will be ignored.
532  // The name "access_locks" are reserved for passing in the permissions
533  if ($name == 'access_locks') continue;
534 
535  $value = $info[0]['value'];
536  require_once SQ_FUDGE_PATH.'/general/text.inc';
537  $keywords = retrieve_keywords_replacements($value);
538  $replacements = Array();
539  foreach ($keywords as $keyword) {
540  $replacements[$keyword] = $asset->getKeywordReplacement($keyword);
541  }//end foreach
542  replace_keywords($value, $replacements);
543  $name = htmlspecialchars($name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
544  $value = htmlspecialchars($value, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
545  $xml .= '<fbmeta name="'.$name.'" content="'.$value.'" />';
546  }//end foreach
547  $xml .= '<fbmeta name="SQUIZASSETID" content="'.$asset->id.'" />';
548  $xml .= '<fbmeta name="SQUIZASSETTYPE" content="'.$asset->type().'" />';
549 
550  $xml .= '</url>';
551 
552  return $xml;
553 
554  }//end _generateXML()
555 
556 
566  public function getAccessLocks($asset)
567  {
568  $am = $GLOBALS['SQ_SYSTEM']->am;
569  /*
570  * Add in the permissions, with the following logic:
571  * - No permissions, return nothing
572  * - Public permission and live status, give a "public" lock
573  * - Specific permission, add the lock
574  */
575  if (!($asset->status & SQ_SC_STATUS_NOT_LIVE)) {
576  $permissions = $am->getPermission($asset->id, SQ_PERMISSION_READ, TRUE);
577  } else {
578  $permissions = $am->getPermission($asset->id, SQ_PERMISSION_WRITE, TRUE);
579  }
580  $public_user_id = $am->getSystemAssetId('public_user');
581  $root_user_id = $am->getSystemAssetId('root_user');
582  $sys_admin_folder_id = $am->getSystemAssetId('system_user_group');
583 
584  // Public user found AND page is live, place in the public lock
585  if (in_array($public_user_id, $permissions) && !($asset->status & SQ_SC_STATUS_NOT_LIVE)) {
586  $permissions[] = 'public';
587  }//end if
588  $all_permissions = Array();
589  foreach ($permissions as $permission) {
590  $all_permissions[] = "'".$this->encodeText(htmlspecialchars($permission, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET))."'";
591  }//end foreach
592 
593  // Give the root user, "GOD" access
594  if (!in_array("'".$root_user_id."'", $all_permissions)) {
595  $all_permissions[] = "'".$this->encodeText(htmlspecialchars($root_user_id, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET))."'";
596  }//end if
597 
598  // also give the system_admin_folder the access
599  if (!in_array("'".$sys_admin_folder_id."'", $all_permissions)) {
600  $all_permissions[] = "'".$this->encodeText(htmlspecialchars($sys_admin_folder_id, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET))."'";
601  }//end if
602 
603  $xml = rtrim(implode(',', $all_permissions), ',');
604 
605  return $xml;
606 
607  }//end getAccessLocks()
608 
609 
624  public function _addEntry($url, $assetid, $root_url, $root_urlid, $live, $xml, $original_url)
625  {
639  $found_url = false;
640  $base_url = $root_url;
641  while ($base_url !== '.') {
642  //if we have reached http:// or https:// break out coz that WILL match
643  if($base_url == 'http:' || $base_url == 'https:') break;
644 
645  if (strpos($url, $base_url) === 0) {
646  $found_url = true;
647  break;
648  }
649  $base_url = dirname($base_url);
650  }
651 
655  if (!$found_url) {
656  return FALSE;
657  }
658 
659  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
660  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
661  try {
662  $check_sql = 'SELECT assetid FROM sq_fnb_idx WHERE url=:url AND assetid=:assetid AND root_url=:root_url';
663  $check_query = MatrixDAL::preparePDOQuery($check_sql);
664  MatrixDAL::bindValueToPdo($check_query, 'url', $url);
665  MatrixDAL::bindValueToPdo($check_query, 'assetid', $assetid);
666  MatrixDAL::bindValueToPdo($check_query, 'root_url', $root_url);
667  $results = MatrixDAL::executePdoOne($check_query);
668  if (empty($results)) {
669  // Entry does not exist, adding a new entry
670  $sql = 'INSERT INTO sq_fnb_idx (url, assetid, root_url, root_urlid, live, xml, original_url) VALUES (:url, :assetid, :root_url, :root_urlid, :live, :xml, :original_url)';
671  $query = MatrixDAL::preparePDOQuery($sql);
672  MatrixDAL::bindValueToPdo($query, 'url', $url);
673  MatrixDAL::bindValueToPdo($query, 'assetid', $assetid);
674  MatrixDAL::bindValueToPdo($query, 'root_url', $root_url);
675  MatrixDAL::bindValueToPdo($query, 'root_urlid', $root_urlid);
676  MatrixDAL::bindValueToPdo($query, 'live', ($live) ? '1' : '0');
677  MatrixDAL::bindValueToPdo($query, 'xml', $xml);
678  MatrixDAL::bindValueToPdo($query, 'original_url', $original_url);
679  MatrixDAL::execPdoQuery($query);
680  }//end if
681  } catch (PDOException $e) {
682  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
683  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
684  trigger_error('Unable to add entry to database: '.$e->getMessage());
685  return FALSE;
686  }
687  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
688  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
689 
690 
691  return TRUE;
692 
693  }//end _addEntry()
694 
695 
704  private function _cleanupEntriesByAssetid($assetid)
705  {
706  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
707  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
708  try {
709  $sql = 'DELETE FROM sq_fnb_idx WHERE assetid=:assetid';
710  $query = MatrixDAL::preparePDOQuery($sql);
711  MatrixDAL::bindValueToPdo($query, 'assetid', $assetid);
712  MatrixDAL::execPdoQuery($query);
713  } catch (PDOException $e) {
714  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
715  trigger_error('Unable to remove entries from database: '.$e->getMessage());
716  return FALSE;
717  }
718  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
719  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
720 
721  return TRUE;
722 
723  }//end _cleanupEntriesByAssetid()
724 
725 
736  public function generateXMLCache($url=NULL, $assetid=0, $public=TRUE)
737  {
738  $results = $this->getXMLCache($url, $assetid, $public);
739 
740  ob_start();
741  echo '<'.'?xml version="1.0" encoding="utf-8"?'.'>';
742  echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
743  foreach ($results as $result) {
744  echo $result['xml']."\n";
745  }//end foreach
746  echo '</urlset>';
747  $contents = ob_get_contents();
748  ob_end_clean();
749 
750  return $contents;
751 
752  }//end generateXMLCache()
753 
754 
766  public function getXMLCache($url=Array(), $assetid=0, $public=TRUE, $excludes=Array())
767  {
768  if (empty($url) || empty($assetid)) {
769  // No parent nor sitemap url found
770  return Array();
771  }//end if
772  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
773  $is_site_asset = !empty($asset) ? ($asset->type() == 'site') : TRUE;
774 
775  $where = Array();
776  $bind_vars = Array();
777  $include_collection_sql = '';
778  $exclude_string = '';
779 
780  // Compile a list of assets to list based on URL
781  foreach ($url as $index => $single_url) {
782  if (!$is_site_asset) {
783  $suburl = substr($single_url, strpos($single_url, '://') + 3);
784  $root_url_info = $GLOBALS['SQ_SYSTEM']->am->getRootURL($suburl);
785  $root_url = array_get_index($root_url_info, 'url', '');
786  $assetid = array_get_index($root_url_info, 'assetid', $assetid);
787 
788  // If the collection is not site, include the collection asset as well
789  $bind_vars['asset_url'.$index] = $single_url;
790  $include_collection_sql = ' OR f.url LIKE :asset_url'.$index;
791  } else {
792  $root_url = $single_url;
793  }
794 
795  $single_url = rtrim($single_url, '/');
796  $root_url = rtrim($root_url, '/');
797  $protocol = parse_url($single_url, PHP_URL_SCHEME);
798  $where[] = '((f.url LIKE :url'.$index.$include_collection_sql.') AND f.root_urlid IN (SELECT urlid FROM sq_ast_url WHERE assetid=:assetid'.$index.')) OR ((f.root_url = :root_url'.$index.' AND f.root_urlid=\'0\') AND (f.original_url LIKE :original_url'.$index.'))';
799  $bind_vars['url'.$index] = $single_url.'/%';
800  $bind_vars['original_url'.$index] = $single_url.'/%';
801  $bind_vars['assetid'.$index] = $assetid;
802  if (strpos($root_url, 'http:') === FALSE && strpos($root_url, 'https:') === FALSE) {
803  $bind_vars['root_url'.$index] = $protocol.'://'.$root_url;
804  } else {
805  $bind_vars['root_url'.$index] = $root_url;
806  }
807  }//end foreach
808 
809  // Compile a list of assets to be excluded based on URL
810  foreach ($excludes as $index => $exclude) {
811  $excluded[] = 'f.url||\'/\' NOT LIKE :exclude'.$index.' OR f.url <> :exclude_asset'.$index;
812  $bind_vars['exclude'.$index] = rtrim($exclude, '/').'/%';
813  $bind_vars['exclude_asset'.$index] = rtrim($exclude, '/');
814  }//end foreach
815  if (!empty($excluded)) {
816  $exclude_string = ' AND (('.implode(') AND (', $excluded).'))';
817  }//end if
818 
819  if (isset($root_url_info)) unset($root_url_info);
820 
821  $db = MatrixDAL::getDb();
822  try {
823  if (MatrixDAL::getDbType() == 'pgsql') {
824  $sql = 'SELECT DISTINCT f.url, f.xml
825  FROM sq_fnb_idx f
826  INNER JOIN sq_ast_lnk l ON l.minorid=f.assetid
827  WHERE l.is_dependant=:dependant';
828  } else {
829  // Oracle fun n games
830  $sql = 'SELECT f.url, f.assetid, f.root_url, f.xml
831  FROM sq_fnb_idx f
832  INNER JOIN sq_ast_lnk l ON l.minorid=f.assetid
833  WHERE l.is_dependant=:dependant';
834  }//end if
835 
836  if ($public) $sql .= ' AND f.live=:live';
837  $sql .= ' AND (';
838  $sql .= rtrim(implode(' OR ', $where), 'OR');
839  $sql .= ')';
840  $sql .= $exclude_string;
841  $sql .= ' ORDER BY f.url';
842 
843  $query = MatrixDAL::preparePDOQuery($sql);
844  MatrixDAL::bindValueToPdo($query, 'dependant', '0');
845  if ($public) MatrixDAL::bindValueToPdo($query, 'live', '1');
846  foreach ($bind_vars as $var_name => $var_value) {
847  MatrixDAL::bindValueToPdo($query, $var_name, $var_value);
848  }//end foreach
849  $results = MatrixDAL::executePdoAssoc($query);
850 
851  } catch (Exception $e) {
852  trigger_error('DB Error '.$e->getMessage());
853  return Array();
854  }
855 
856  // If Oracle, we're not quite done yet
857  if (MatrixDAL::getDbType() == 'oci' && !empty($results)) {
858  $unique_results = Array();
859  foreach($results as $key => $result) {
860  // get rid of all the duplicate entires
861  if (isset($unique_results[$result['url'].'|'.$result['assetid'].'|'.$result['root_url']])) {
862  unset($results[$key]);
863  } else {
864  $unique_results[$result['url'].'|'.$result['assetid'].'|'.$result['root_url']] = 1;
865  }
866  }
867  unset($unique_results);
868  }
869 
870  return $results;
871 
872  }//end getXMLCache()
873 
874 
884  protected function _getSiteURL($root_urlid='0', &$asset, $asset_url)
885  {
886  $site_url = Array();
887 
888  if (empty($root_urlid)) {
889  // Empty root_urlid, then most likely file is public, so just grab the site urls
890  $sites = array_keys($GLOBALS['SQ_SYSTEM']->am->getParents($asset->id, 'site', TRUE));
891  $urls = Array();
892  foreach ($sites as $site) {
893  $url_info = $GLOBALS['SQ_SYSTEM']->am->getUrls($site);
894  foreach ($url_info as $info) {
895  $urls[] = $info;
896  }//end foreach
897  }//end foreach
898 
899  if (!empty($urls)) {
900  foreach ($urls as $details) {
901  $http = array_get_index($details, 'http', 0);
902  $https = array_get_index($details, 'https', 0);
903  $url = array_get_index($details, 'url', '');
904 
905  // *Sigh* ignore empty urls
906  if (empty($url)) continue;
907 
908  // Make sure we only accept site urls which has the same root domain as __data file url
909  $system_root_url = sq_root_url($asset_url, FALSE);
910  if(strpos($url, $system_root_url) !== 0) continue;
911 
912  // Create the site url
913  if ($http) {
914  $site_url[] = 'http://'.$url;
915  }//end if
916  if ($https) {
917  $site_url[] = 'https://'.$url;
918  }//end if
919  }//end foreach
920  }//end if
921  } else {
922  // We have a root_urlid, find out the site url
923  $db = MatrixDAL::getDb();
924  try {
925  $sql = 'SELECT http, https, url FROM sq_ast_url WHERE urlid=:urlid';
926  $query = MatrixDAL::preparePDOQuery($sql);
927  MatrixDAL::bindValueToPdo($query, 'urlid', $root_urlid);
928  $results = MatrixDAL::executePdoAssoc($query);
929  } catch (Exception $e) {
930  trigger_error('DB Error '.$e->getMessage());
931  return $site_url;
932  }//end try-catch
933 
934  if (!empty($results)) {
935  // Only care about the first result (it should be the only result)
936  $result = $results[0];
937  $http = array_get_index($result, 'http', 0);
938  $https = array_get_index($result, 'https', 0);
939  $url = array_get_index($result, 'url', '');
940 
941  if (($http) && !empty($url)) {
942  $site_url[] = 'http://'.$url;
943  }//end if
944 
945  if (($https) && !empty($url)) {
946  $site_url[] = 'https://'.$url;
947  }//end if
948  }//end if
949  }//end if
950 
951  return $site_url;
952 
953  }//end _getSiteURL()
954 
955 
956 // --- FUNNELBACK COLLECTIONS FUNCTIONS --- //
957 
958 
967  public function isCollectionValid($collection_id)
968  {
969  $collections = $this->getCollections();
970 
971  if (isset($collections[$collection_id]['valid']) && $collections[$collection_id]['valid'] === TRUE) {
972  return TRUE;
973  }//end if
974 
975  return FALSE;
976 
977  }//end isCollectionValid()
978 
979 
986  public function getCollections()
987  {
988  $collections = $this->attr('collections');
989 
990  return $collections;
991 
992  }//end getCollections()
993 
994 
1003  public function getCollectionName($collection_id)
1004  {
1005  $collections = $this->attr('collections');
1006  $collection = array_get_index($collections, $collection_id, Array());
1007  return array_get_index($collection, 'name', '');
1008 
1009  }//end getCollectionName()
1010 
1011 
1021  public function getCollectionDataPath($collection_id, $sub_dir='')
1022  {
1023  $path = '';
1024  $fb_data_path = $this->data_path;
1025  $collections = $this->getCollections();
1026  if (empty($collection_id)) return $path;
1027  if (!isset($collections[$collection_id])) return $path;
1028 
1029  $path = $fb_data_path.'/'.$collection_id;
1030  if (!empty($sub_dir)) $path .= '/'.$sub_dir;
1031  if (!is_dir($path) && !is_writable($path)) {
1032  // Path may not exist, try and create it
1033  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1034  $status = create_directory($path);
1035  if ($status === FALSE) {
1036  // Error error error
1037  trigger_localised_error('FNB0013', E_USER_WARNING);
1038  $path = '';
1039  }//end if
1040  }//end if
1041 
1042  return $path;
1043 
1044  }//end getCollectionDataPath()
1045 
1046 
1055  function getCollectionConfigFiles($collection_id)
1056  {
1057  $config = Array();
1058  $path = $this->getCollectionDataPath($collection_id, 'conf');
1059  if (empty($path)) return $config;
1060 
1061  $config['executables'] = $path.'/executables.cfg';
1062  $config['collection'] = $path.'/collection.cfg';
1063  $config['fluster'] = $path.'/contextual_navigation.cfg';
1064  $config['metadata'] = $path.'/metamap.cfg';
1065  $config['xml'] = $path.'/xml.cfg';
1066 
1067  return $config;
1068 
1069  }//end getCollectionConfigFiles()
1070 
1071 
1081  function createCollectionConfig($file, $config)
1082  {
1083  $config = (string) $config;
1084  switch ($config) {
1085  case 'collection':
1086  $default_file = $this->getFunnelbackPath().'/conf/collection.cfg';
1087  if (file_exists($default_file) && !file_exists($file)) {
1088  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1089  copy_file($default_file, $file);
1090  }//end if
1091  break;
1092 
1093  case 'executables':
1094  $default_file = $this->getFunnelbackPath().'/conf/executables.cfg';
1095  if (file_exists($default_file) && !file_exists($file)) {
1096  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1097  copy_file($default_file, $file);
1098  }//end if
1099  break;
1100 
1101  case 'fluster':
1102  case 'fluster.cfg':
1103  case 'contextual_navigation.cfg':
1104  $default_file = $this->getFunnelbackPath().'/conf/contextual_navigation.cfg';
1105  if (file_exists($default_file) && !file_exists($file)) {
1106  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1107  copy_file($default_file, $file);
1108  $lines = $this->readConfiguration($file, 'fluster');
1109  $this->writeConfiguration($file, $lines, 'fluster');
1110  }//end if
1111  break;
1112 
1113  case 'metadata':
1114  case 'metamap':
1115  case 'metamap.cfg':
1116  $default_file = $this->getFunnelbackPath().'/conf/metamap.cfg';
1117  if (file_exists($default_file) && !file_exists($file)) {
1118  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1119  copy_file($default_file, $file);
1120  $lines = $this->readConfiguration($file, 'metadata', ',');
1121  $this->writeConfiguration($file, $lines, 'metadata', ',');
1122  }//end if
1123  break;
1124 
1125  case 'xml':
1126  $default_file = $this->getFunnelbackPath().'/conf/xml.cfg';
1127  if (file_exists($default_file) && !file_exists($file)) {
1128  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1129  copy_file($default_file, $file);
1130  }//end if
1131  break;
1132 
1133  default:
1134  // Meh
1135  break;
1136  }//end switch
1137 
1138  }//end createCollectionConfig()
1139 
1140 
1148  {
1149  return Array(
1150  'web' => translate('funnelback_collection_type_web'),
1151  'meta' => translate('funnelback_collection_type_meta'),
1152  );
1153 
1154  }//end _getCollectionTypes()
1155 
1156 
1157 // --- FUNNELBACK INDEXING FUNCTIONS --- //
1158 
1159 
1167  {
1168  $options = Array();
1169  $available_opts = Array(
1170  'politeness' => '-politeness',
1171  // 'orgname' => '-O',
1172  'spelleroff' => '-spelleroff',
1173  'spelling_threshold' => '-spelling_threshold',
1174  'ibd' => '-ibd',
1175  'ixcom' => '-ixcom',
1176  );
1177 
1178  // Add some defaults
1179  $options[] = '-annie';
1180  $options[] = '-cleanup';
1181 
1182  // Now add in the user-specified options
1183  foreach ($available_opts as $opt_name => $opt_switch) {
1184  $attribute = $this->attr($opt_name);
1185  if (in_array($opt_name, Array('politeness', 'spelling_threshold')) && $attribute == '0') {
1186  // Special case for politeness to work on 0, ie. we dont want to be polite ;-)
1187  $options[] = $opt_switch.'0';
1188  } else if ($opt_name == 'orgname') {
1189  // Special case for orgname to escape the option
1190  if (!empty($attribute)) {
1191  $options[] = '-O'.escapeshellarg($attribute);
1192  }//end if
1193  } else {
1194  if (!empty($attribute)) {
1195  if (in_array($opt_name, Array('politeness', 'spelling_threshold'))) {
1196  $options[] = $opt_switch.$attribute;
1197  } else {
1198  $options[] = $opt_switch;
1199  }//end if
1200  }//end if
1201  }//end if
1202  }//end foreach
1203 
1204  return $options;
1205 
1206  }//end getIndexingOptions()
1207 
1208 
1209 // --- HELPER FUNCTIONS --- //
1210 
1211 
1223  function readConfiguration($config, $type='thesaurus', $delimiter='=', $system=FALSE)
1224  {
1225  $data = Array();
1226  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1227  $contents = file_to_string($config);
1228  $lines = explode("\n", $contents);
1229  switch ($type) {
1230  case 'feature':
1231  foreach ($lines as $line) {
1232  if (strpos($line, $delimiter) !== FALSE) {
1233  // Found a config line
1234  $line_contents = explode($delimiter, $line);
1235  // Need to figure out what is set
1236  $number_elements = count($line_contents);
1237  $trigger = NULL;
1238  $title = NULL;
1239  $desc = NULL;
1240  $url = NULL;
1241  $query = 'substring';
1242  if ($number_elements == 4) {
1243  // 4 Elements - trigger, title, desc, url
1244  $trigger = array_get_index($line_contents, 0, '');
1245  $title = array_get_index($line_contents, 1, '');
1246  $desc = array_get_index($line_contents, 2, '');
1247  $url = array_get_index($line_contents, 3, '');
1248  } else if ($number_elements == 3) {
1249  // 3 Elements - trigger, title, url
1250  $trigger = array_get_index($line_contents, 0, '');
1251  $title = array_get_index($line_contents, 1, '');
1252  $url = array_get_index($line_contents, 3, '');
1253  } else {
1254  // Guessing 2 elements - trigger, url
1255  $trigger = array_get_index($line_contents, 0, '');
1256  $url = array_get_index($line_contents, 3, '');
1257  }//end if
1258 
1259  // Needed to process *at least* a trigger and url
1260  if (!empty($trigger) && !empty($url)) {
1261  if (strpos($trigger, '~') === 0) {
1262  $trigger = substr($trigger, 1);
1263  $query = 'regex';
1264  } else if (strpos($trigger, '%') === 0) {
1265  $trigger = substr($trigger, 1);
1266  $query = 'term';
1267  } else if (strpos($trigger, '+') === 0) {
1268  $trigger = substr($trigger, 1);
1269  $query = 'exact';
1270  }//end if
1271 
1272  $data_line = Array(
1273  'query' => $query,
1274  'trigger' => $trigger,
1275  'url' => $url,
1276  );
1277  if (!empty($title)) $data_line['title'] = $title;
1278  if (!empty($desc)) $data_line['desc'] = $desc;
1279  $data[] = $data_line;
1280  }//end if
1281  }//end if
1282  }//end foreach
1283  break;
1284 
1285  case 'fluster':
1286  foreach ($lines as $line) {
1287  $line = trim($line);
1288  if (!empty($line) && ((strpos($line, '#') !== 0) || (strpos($line, $delimiter) !== FALSE))) {
1289  $line_data = explode($delimiter, $line);
1290  if (isset($line_data[0]) && !empty($line_data[0])) {
1291  // These settings do not need to be saved as they are used exclusively by the search page
1292  $invalid = Array(
1293  'enable_fluster',
1294  'site.max_clusters',
1295  'type.max_clusters',
1296  'topic.max_clusters',
1297  );
1298  if (!in_array($line_data[0], $invalid)) {
1299  $data[$line_data[0]] = $line_data[1];
1300  }//end if
1301  }//end if
1302  }//end if
1303  }//end foreach
1304  break;
1305 
1306  case 'metadata':
1307  foreach ($lines as $line) {
1308  $line = trim($line);
1309  if (!empty($line) && ((strpos($line, '#') !== 0) && (strpos($line, $delimiter) !== FALSE))) {
1310  $line_data = explode($delimiter, $line);
1311  if (!empty($line_data[0]) && isset($line_data[1]) && !empty($line_data[2])) {
1312  $alias = $line_data[0];
1313  $content = (($line_data[1] == '1') ? '1' : '0');
1314  $metatag = $line_data[2];
1315  $found_comment = strpos($metatag, '#');
1316  if ($found_comment !== FALSE) {
1317  $metatag = substr($metatag, 0, $found_comment);
1318  }//end if
1319  $data[] = Array(
1320  'alias' => $alias,
1321  'content' => $content,
1322  'metatag' => trim($metatag),
1323  'system' => TRUE,
1324  );
1325  }//end if
1326  }//end if
1327  }//end foreach
1328 
1329  // This *has* to be in the entries for access_locks
1330  $data[] = Array(
1331  'alias' => 'S',
1332  'content' => '1',
1333  'metatag' => 'access_locks',
1334  'system' => TRUE,
1335  );
1336  break;
1337 
1338  case 'thesaurus':
1339  default:
1340  foreach ($lines as $line) {
1341  if (strpos($line, $delimiter) !== FALSE) {
1342  // Found a config line
1343  $line_contents = explode($delimiter, $line);
1344  $query = array_get_index($line_contents, 0, '%');
1345  $term = array_get_index($line_contents, 1, '');
1346  $expansion = array_get_index($line_contents, 2, '');
1347  if ($query == '+') {
1348  $query_exp = 'whole';
1349  } else if ($query == '~') {
1350  $query_exp = 'regex';
1351  } else if ($query == '%') {
1352  $query_exp = 'term';
1353  }
1354 
1355  if (!empty($term) && !empty($expansion)) {
1356  // No point having a nothing there
1357  $data[] = Array(
1358  'query' => $query_exp,
1359  'term' => $term,
1360  'expansion' => $expansion,
1361  );
1362  }//end if
1363  }//end if
1364  }//end foreach
1365  break;
1366  }//end switch
1367 
1368  return $data;
1369 
1370  }//end readConfiguration()
1371 
1372 
1384  function writeConfiguration($config, $data=Array(), $type='thesaurus', $delimiter='=')
1385  {
1386  $status = FALSE;
1387  $contents = '';
1388  switch ($type) {
1389  case 'feature':
1390  foreach ($data as $line) {
1391  $query = array_get_index($line, 'query', 'substring');
1392  $trigger = array_get_index($line, 'trigger', '');
1393  $title = array_get_index($line, 'title', '');
1394  $desc = array_get_index($line, 'desc', '');
1395  $url = array_get_index($line, 'url', '');
1396  $pre_line = '';
1397  if ($query == 'exact') {
1398  $pre_line = '+';
1399  } else if ($query == 'term') {
1400  $pre_line = '%';
1401  } else if ($query == 'regex') {
1402  $pre_line = '~';
1403  }//end if
1404 
1405  if (!empty($trigger) && !empty($url)) {
1406  // At bare minimum, we need a trigger and url to write
1407  $contents .= $pre_line.$trigger.$delimiter;
1408  if (!empty($title)) $contents .= $title.$delimiter;
1409  if (!empty($desc)) $contents .= $desc.$delimiter;
1410  $contents .= $url."\n";
1411  }//end if
1412  }//end foreach
1413  break;
1414 
1415  case 'fluster':
1416  $contents .= "#\n";
1417  $contents .= "# Fluster Configuration\n";
1418  $contents .= "#\n";
1419  // These settings do not need to be saved as they are used exclusively by the search page
1420  $invalid = Array(
1421  'enable_fluster',
1422  'site.max_clusters',
1423  'type.max_clusters',
1424  'topic.max_clusters',
1425  );
1426  ksort($data);
1427  foreach ($data as $switch => $parameter) {
1428  if (in_array($switch, $invalid)) continue;
1429  $contents .= $switch.$delimiter.$parameter."\n";
1430  }//end foreach
1431  break;
1432 
1433  case 'metadata':
1434  $contents .= "#\n";
1435  $contents .= "# Metadata Mapping Configuration\n";
1436  $contents .= "#\n";
1437  foreach ($data as $line) {
1438  $alias = array_get_index($line, 'alias', '');
1439  $field = array_get_index($line, 'content', 0);
1440  $metag = array_get_index($line, 'metatag', '');
1441  if (!empty($metag) || $alias != 'S') {
1442  $contents .= $alias.$delimiter.$field.$delimiter.$metag."\n";
1443  }//end if
1444  }//end foreach
1445 
1446  // Finally, add in the access locks
1447  $contents .= 'S,4,access_locks'."\n";
1448  break;
1449 
1450  case 'thesaurus':
1451  default:
1452  $contents = "PADRE Thesaurus Version: 2\n";
1453  foreach ($data as $line) {
1454  $query = array_get_index($line, 'query', '%');
1455  $term = array_get_index($line, 'term', '');
1456  $expansion = array_get_index($line, 'expansion', '');
1457 
1458  if (!empty($term) && !empty($expansion)) {
1459  $contents .= $query.$delimiter.$term.$delimiter.$expansion."\n";
1460  }//end if
1461  }//end foreach
1462  break;
1463  }//end switch
1464 
1465  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1466  $status = string_to_file($contents, $config);
1467 
1468  return $status;
1469 
1470  }//end writeConfiguration()
1471 
1472 
1486  function runCommand($command, &$output, $input=NULL, $log_file=NULL, $cwd=NULL, $environment=Array())
1487  {
1488  // Default variables and environment settings
1489  $fm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('funnelback_manager');
1490  $search_home = $this->getFunnelbackPath();
1491  $environment['SEARCH_HOME'] = $search_home;
1492  if (!isset($environment['SITE_SEARCH_ROOT']) && !is_null($cwd)) {
1493  $environment['SITE_SEARCH_ROOT'] = $cwd;
1494  }//end if
1495  if (is_null($log_file)) {
1496  $log = Array(
1497  'pipe',
1498  'w',
1499  );
1500  } else {
1501  $log = Array(
1502  'file',
1503  $log_file,
1504  'a',
1505  );
1506  }//end if
1507 
1508  $status = FALSE;
1509  $spec = Array(
1510  0 => Array(
1511  'pipe',
1512  'r',
1513  ), // stdin is a pipe that the child will read from
1514  1 => $log, // stdout is a pipe that the child will write to
1515  2 => $log, // stderr is a file to write to
1516  );
1517 
1518  $process = proc_open($command, $spec, $pipes, $cwd, $environment);
1519 
1520  if (is_resource($process)) {
1521  // Add the input if requested
1522  if (!is_null($input)) {
1523  fwrite($pipes[0], $input);
1524  fclose($pipes[0]);
1525  }
1526 
1527  if (is_null($log_file)) {
1528  // Get the output
1529  $output .= stream_get_contents($pipes[1]);
1530  fclose($pipes[1]);
1531 
1532  // Find the errors ... do NOT throw to output
1533  $errors = stream_get_contents($pipes[2]);
1534  if (!empty($errors)) {
1535  error_log("Funnelback Command failed, see funnelback.log for additional detail.");
1536  log_write($errors, 'funnelback');
1537  }//end if
1538  fclose($pipes[2]);
1539  }//end if
1540 
1541  // Finally, get the status of this command
1542  $status = proc_close($process);
1543  }//end if
1544 
1545  return $status;
1546 
1547  }//end runCommand()
1548 
1549 
1561  public function encodeText($text)
1562  {
1563  // Strip disallowed characters (0-0x20 and 0x7F-0xA0)
1564  $pattern = Array();
1565  for ($i=0; $i<32; $i++) {
1566  $pattern[] = chr($i);
1567  }//end for
1568  for ($i=127; $i<161; $i++) {
1569  $pattern[] = chr($i);
1570  }//end for
1571 
1572  foreach ($pattern as $patt) {
1573  if (SQ_CONF_DEFAULT_CHARACTER_SET == 'utf-8' && function_exists('mb_substr') && function_exists('mb_strlen') && function_exists('mb_strpos')) {
1574  // Bug #4240 - when dealing with 2 byte utf8 characters, str_replace just ain't up to scratch
1575  $patt = utf8_encode($patt);
1576  $replace = '';
1577  $pos = mb_strpos($text, $patt);
1578  while ($pos !== FALSE) {
1579  $text = mb_substr($text, 0, $pos).$replace.mb_substr($text, $pos + mb_strlen($patt));
1580  $pos = mb_strpos($text, $patt, $pos+mb_strlen($replace));
1581  }
1582  } else {
1583  $text = str_replace($patt, '', $text);
1584  }//end if
1585  }
1586 
1587  // Remove Quote marks
1588  $text = str_replace('"', '', $text);
1589  $text = str_replace("'", '', $text);
1590 
1591  // Remove spaces (character 0x20)
1592  $text = str_replace(' ', '', $text);
1593  $text = str_replace('&nbsp;', '', $text);
1594 
1595  return $text;
1596 
1597  }//end encodeText()
1598 
1599 
1609  public function decodeText($text)
1610  {
1611  // Reinstate Quote marks
1612  $text = str_replace('&ldquo;', '"', $text);
1613  $text = str_replace('&lsquo;', "'", $text);
1614 
1615  // Reinstate Space
1616  $text = str_replace('&nbsp;', ' ', $text);
1617 
1618  return $text;
1619 
1620  }//end decodeText()
1621 
1622 
1629  public function getMetadataAliases()
1630  {
1631  return Array(
1632  // ''=> 'Anywhere', // DISABLED until tested properly
1633  'a' => translate('fb_mclass', 'a'), // Author
1634  'b' => translate('fb_mclass', 'b'), // Rights
1635  'c' => translate('fb_mclass', 'c'), // Description
1636  'd' => translate('fb_mclass', 'd'), // Date
1637  'e' => translate('fb_mclass', 'e'), // Type
1638  'f' => translate('fb_mclass', 'f'), // Format
1639  'g' => translate('fb_mclass', 'g'), // Relation
1640  'h' => translate('fb_mclass', 'h'), // Outgoing Links
1641  'i' => translate('fb_mclass', 'i'), // Images
1642  'j' => translate('fb_mclass', 'j'), // Availability
1643  'k' => translate('fb_mclass', 'k'), // Anchor Text
1644  'l' => translate('fb_mclass', 'l'), // Language
1645  'm' => translate('fb_mclass', 'm'), // Mailto references
1646  'n' => translate('fb_mclass', 'n'), // Source
1647  'o' => translate('fb_mclass', 'o'), // Coverage
1648  'p' => translate('fb_mclass', 'p'), // Publisher
1649  'q' => translate('fb_mclass', 'q'), // Function
1650  'r' => translate('fb_mclass', 'r'), // Recipients
1651  's' => translate('fb_mclass', 's'), // Subject/Keywords
1652  't' => translate('fb_mclass', 't'), // Title
1653  'u' => translate('fb_mclass', 'u'), // Hostname part of URL
1654  'v' => translate('fb_mclass', 'v'), // Filename part of URL
1655  'w' => translate('fb_mclass', 'w'),
1656  'x' => translate('fb_mclass', 'x'),
1657  'y' => translate('fb_mclass', 'y'),
1658  'z' => translate('fb_mclass', 'z'),
1659  'A' => translate('fb_mclass', 'A'),
1660  'B' => translate('fb_mclass', 'B'),
1661  'C' => translate('fb_mclass', 'C'),
1662  'D' => translate('fb_mclass', 'D'),
1663  'E' => translate('fb_mclass', 'E'),
1664  'F' => translate('fb_mclass', 'F'),
1665  'G' => translate('fb_mclass', 'G'),
1666  'H' => translate('fb_mclass', 'H'),
1667  'I' => translate('fb_mclass', 'I'),
1668  'J' => translate('fb_mclass', 'J'),
1669  'K' => translate('fb_mclass', 'K'), // Click Data
1670  'L' => translate('fb_mclass', 'L'),
1671  'M' => translate('fb_mclass', 'M'),
1672  'N' => translate('fb_mclass', 'N'),
1673  'O' => translate('fb_mclass', 'O'),
1674  'P' => translate('fb_mclass', 'P'),
1675  'Q' => translate('fb_mclass', 'Q'),
1676  'R' => translate('fb_mclass', 'R'),
1677  'S' => translate('fb_mclass', 'S'), // Squiz Access keys
1678  'T' => translate('fb_mclass', 'T'),
1679  'U' => translate('fb_mclass', 'U'),
1680  'V' => translate('fb_mclass', 'V'),
1681  'W' => translate('fb_mclass', 'W'),
1682  'X' => translate('fb_mclass', 'X'),
1683  'Y' => translate('fb_mclass', 'Y'),
1684  'Z' => translate('fb_mclass', 'Z'),
1685  '0' => translate('fb_mclass', '0'),
1686  '1' => translate('fb_mclass', '1'),
1687  '2' => translate('fb_mclass', '2'),
1688  '3' => translate('fb_mclass', '3'),
1689  '4' => translate('fb_mclass', '4'),
1690  '5' => translate('fb_mclass', '5'),
1691  '6' => translate('fb_mclass', '6'),
1692  '7' => translate('fb_mclass', '7'),
1693  '8' => translate('fb_mclass', '8'),
1694  '9' => translate('fb_mclass', '9'),
1695  );
1696 
1697  }//end getMetadataAliases()
1698 
1699 
1706  public function getFunnelbackPath()
1707  {
1708  return '/opt/funnelback-oem';
1709 
1710  }//end getFunnelbackPath()
1711 
1712 
1720  public function getNullQueryKeyword()
1721  {
1722  return '!NOdfadksjflTERMSdsjdskfSUBMITTED';
1723 
1724  }//end getNullQueryKeyword()
1725 
1726 
1733  public function checkInstalled()
1734  {
1735  $installed = TRUE;
1736  $search_dir = $this->getFunnelbackPath();
1737  foreach ($this->getRequiredFiles(TRUE) as $file) {
1738  if (!file_exists($search_dir.'/'.$file) && !is_readable($search_dir.'/'.$file)) {
1739  $installed = FALSE;
1740  }//end if
1741  }//end foreach
1742 
1743  return $installed;
1744 
1745  }//end checkInstalled()
1746 
1747 
1756  public function getRequiredFiles($path=FALSE)
1757  {
1758  $indexer = (($path) ? 'bin/' : '').'padre-iw';
1759  $search = (($path) ? 'bin/' : '').'padre-sw';
1760  $fl = (($path) ? 'bin/' : '').'padre-fl';
1761  $annie = (($path) ? 'bin/' : '').'annie-a';
1762  $spelling = (($path) ? 'bin/' : '').'build_spelling_index';
1763  $click = (($path) ? 'bin/' : '').'clix2anx';
1764  $config_xml = (($path) ? 'conf/' : '').'xml.cfg';
1765  $config_metamap = (($path) ? 'conf/' : '').'metamap.cfg';
1766  $config_fluster = (($path) ? 'conf/' : '').'contextual_navigation.cfg';
1767  $licence = (($path) ? 'VERSION/' : '').'squiz.lic';
1768  $files = Array(
1769  $indexer,
1770  $search,
1771  $fl,
1772  $annie,
1773  $spelling,
1774  $click,
1775  $config_xml,
1776  $config_metamap,
1777  $config_fluster,
1778  $licence,
1779  );
1780 
1781  return $files;
1782 
1783  }//end getRequiredFiles()
1784 
1785 
1786 }//end class
1787 
1788 ?>