Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezurlaliasml.php
Go to the documentation of this file.
1 <?php
57 class eZURLAliasML extends eZPersistentObject
58 {
59 // Return values from storePath()
60 const LINK_ID_NOT_FOUND = 1;
61 const LINK_ID_WRONG_ACTION = 2;
62 const LINK_ALREADY_TAKEN = 3;
63 const ACTION_INVALID = 51;
64 const DB_ERROR = 101;
65
71 public $Path;
72
76 public $ID;
77
81 public $Parent;
82
86 public $Link;
87
91 public $Text;
92
96 public $TextMD5;
97
101 public $LangMask;
102
106 public $Action;
107
111 public $ActionType;
112
116 public $AliasRedirects;
117
121 public $IsAlias;
122
126 public $IsOriginal;
127
131 private static $charset = null;
132
133 public function __construct( $row )
134 {
135 parent::__construct( $row );
136 $this->Path = null;
137 if ( isset( $row['path'] ) )
138 {
139 $this->Path = $row['path'];
140 }
141 }
142
143 static public function definition()
144 {
145 static $definition = array( "fields" => array( "id" => array( 'name' => 'ID',
146 'datatype' => 'integer',
147 'default' => 0,
148 'required' => true ),
149 "parent" => array( 'name' => 'Parent',
150 'datatype' => 'integer',
151 'default' => 0,
152 'required' => true ),
153 "lang_mask" => array( 'name' => 'LangMask',
154 'datatype' => 'integer',
155 'default' => 0,
156 'required' => true ),
157 "text" => array( 'name' => 'Text',
158 'datatype' => 'string',
159 'default' => '',
160 'required' => true ),
161 "text_md5" => array( 'name' => 'TextMD5',
162 'datatype' => 'string',
163 'default' => '',
164 'required' => true ),
165 "action" => array( 'name' => 'Action',
166 'datatype' => 'string',
167 'default' => '',
168 'required' => true ),
169 "action_type" => array( 'name' => 'ActionType',
170 'datatype' => 'string',
171 'default' => '',
172 'required' => true ),
173 "link" => array( 'name' => 'Link',
174 'datatype' => 'integer',
175 'default' => 0,
176 'required' => true ),
177 "is_alias" => array( 'name' => 'IsAlias',
178 'datatype' => 'integer',
179 'default' => 0,
180 'required' => true ),
181 "is_original" => array( 'name' => 'IsOriginal',
182 'datatype' => 'integer',
183 'default' => 0,
184 'required' => true ),
185 "alias_redirects" => array( 'name' => 'AliasRedirects',
186 'datatype' => 'integer',
187 'default' => 1,
188 'required' => true ) ),
189 "keys" => array( "parent", "text_md5" ),
190 "function_attributes" => array( "children" => "getChildren",
191 "path" => "getPath" ),
192 "class_name" => "eZURLAliasML",
193 "name" => "ezurlalias_ml" );
194 return $definition;
195 }
196
200 static function strtolower( $text )
201 {
202 //We need to detect our internal charset
203 if ( self::$charset === null )
204 {
205 self::$charset = eZTextCodec::internalCharset();
206 }
207
208 //First try to use mbstring
209 if ( extension_loaded( 'mbstring' ) )
210 {
211 return mb_strtolower( $text, self::$charset );
212 }
213 else
214 {
215 // Fall back if mbstring is not available
216 $char = eZCharTransform::instance();
217 return $char->transformByGroup( $text, 'lowercase' );
218 }
219 }
220
225 function actionURL()
226 {
227 return eZURLAliasML::actionToUrl( $this->Action );
228 }
229
239 static function create( $element, $action, $parentID, $language )
240 {
241 $row = array( 'text' => $element,
242 'text_md5' => md5( eZURLAliasML::strtolower( $element ) ),
243 'parent' => $parentID,
244 'lang_mask' => $language,
245 'action' => $action );
246 return new eZURLAliasML( $row );
247 }
248
252 function setAttribute( $name, $value )
253 {
254 parent::setAttribute( $name, $value );
255 if ( $name == 'text' )
256 {
257 $this->TextMD5 = md5( eZURLAliasML::strtolower( $value ) );
258 }
259 else if ( $name == 'action' )
260 {
261 $this->ActionType = null;
262 }
263 }
264
270 function store( $fieldFilters = null )
271 {
272 if ( $this->ID === null )
273 {
274 $this->ID = self::getNewID();
275 }
276 if ( $this->Link === null )
277 {
278 $this->Link = $this->ID;
279 }
280 if ( $this->TextMD5 === null )
281 {
282 $this->TextMD5 = md5( eZURLAliasML::strtolower( $this->Text ) );
283 }
284 $this->IsOriginal = ($this->ID == $this->Link) ? 1 : 0;
285 if ( $this->IsAlias )
286 $this->IsOriginal = true;
287 if ( $this->Action == "nop:" ) // nop entries can always be replaced
288 $this->IsOriginal = false;
289 if ( strlen( $this->ActionType ) == 0 )
290 {
291 if ( preg_match( "#^(.+):#", $this->Action, $matches ) )
292 $this->ActionType = $matches[1];
293 else
294 $this->ActionType = 'nop';
295 }
296
297 parent::store( $fieldFilters );
298 }
299
304 static public function removeByAction( $actionName, $actionValue )
305 {
306 // If this is an original element we must get rid of all elements which points to it.
307 $db = eZDB::instance();
308 $actionStr = $db->escapeString( $actionName . ':' . $actionValue );
309 $query = "DELETE FROM ezurlalias_ml WHERE action = '{$actionStr}'";
310 $db->query( $query );
311 }
312
323 public static function removeSingleEntry( $parentID, $textMD5, $language )
324 {
325 $parentID = (int)$parentID;
326 if ( !is_object( $language ) )
327 $language = eZContentLanguage::fetchByLocale( $language );
328 $languageID = (int)$language->attribute( 'id' );
329 $db = eZDB::instance();
330
331 $bitDel = $db->bitAnd( 'lang_mask' , (~$languageID) );
332 $bitMatch = $db->bitAnd( 'lang_mask', $languageID ) . ' > 0';
333 $bitMask = $db->bitAnd( 'lang_mask', ~1 );
334
335
336 // Fetch data for the given entry
337 $rows = $db->arrayQuery( "SELECT * FROM ezurlalias_ml WHERE parent = {$parentID} AND text_md5 = '" . $db->escapeString( $textMD5 ) . "' AND $bitMatch" );
338 if ( count( $rows ) == 0 )
339 return false;
340
341 $id = (int)$rows[0]['id'];
342 $mask = (int)$rows[0]['lang_mask'];
343 if ( ($mask & ~($languageID | 1)) == 0 )
344 {
345 // No more languages for this entry so we need to check for children
346 $childRows = $db->arrayQuery( "SELECT * FROM ezurlalias_ml WHERE parent = {$id}" );
347 if ( count( $childRows ) > 0 )
348 {
349 // Turn entry into a nop: to disable it
350 $element = new eZURLAliasML( $rows[0] );
351 $element->LangMask = 1;
352 $element->Action = "nop:";
353 $element->ActionType = "nop";
354 $element->IsAlias = 0;
355 $element->store();
356 return;
357 }
358 }
359 // Remove language bit from selected entries and remove entries which have no languages.
360 $db->query( "UPDATE ezurlalias_ml SET lang_mask = $bitDel WHERE parent = {$parentID} AND text_md5 = '" . $db->escapeString( $textMD5 ) . "' AND $bitMatch" );
361 $db->query( "DELETE FROM ezurlalias_ml WHERE parent = {$parentID} AND text_md5 = '" . $db->escapeString( $textMD5 ) . "' AND $bitMask = 0" );
362 }
363
369 function getChildren()
370 {
371 return eZURLAliasML::fetchByParentID( $this->ID, true, true, false );
372 }
373
383 function getPath( $locale = null, $incomingLanguageList = null )
384 {
385 if ( $this->Path !== null )
386 return $this->Path;
387
388 // Fetch path 'text' elements of correct parent path
389 $path = array( $this->Text );
390 $id = (int)$this->Parent;
391 $db = eZDB::instance();
392 while ( $id != 0 )
393 {
394 $query = "SELECT parent, lang_mask, text FROM ezurlalias_ml WHERE id={$id}";
395 if ( $locale !== null && is_string( $locale ) )
396 {
397 // We also want to consider the prioritized language list for the
398 // destination siteaccess, so that untranslated objects, are not
399 // disregarded from the URL.
400 if ( $incomingLanguageList !== null )
401 {
402 eZContentLanguage::setPrioritizedLanguages( $incomingLanguageList );
403 }
404
405 $langMask = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
406 $query .= " AND ({$langMask})";
407 }
408 $rows = $db->arrayQuery( $query );
409
410 if ( count( $rows ) == 0 )
411 {
412 if ( $incomingLanguageList !== null )
413 {
414 eZContentLanguage::clearPrioritizedLanguages();
415 }
416 break;
417 }
418 $result = eZURLAliasML::choosePrioritizedRow( $rows );
419
420 if ( $incomingLanguageList !== null )
421 {
422 eZContentLanguage::clearPrioritizedLanguages();
423 }
424
425 if ( !$result )
426 {
427 $result = $rows[0];
428 }
429 $id = (int)$result['parent'];
430 array_unshift( $path, $result['text'] );
431 }
432 $this->Path = implode( '/', $path );
433 return $this->Path;
434 }
435
454 static function storePath( $path, $action,
455 $languageName = false, $linkID = false, $alwaysAvailable = false, $rootID = false,
456 $cleanupElements = true, $autoAdjustName = false, $reportErrors = true, $aliasRedirects = true )
457 {
458 $path = eZURLAliasML::cleanURL( $path );
459 if ( $languageName === false )
460 {
461 $languageName = eZContentLanguage::topPriorityLanguage();
462 }
463 if ( is_object( $languageName ) )
464 {
465 $languageObj = $languageName;
466 $languageID = (int)$languageName->attribute( 'id' );
467 $languageName = $languageName->attribute( 'locale' );
468 }
469 else
470 {
471 $languageObj = eZContentLanguage::fetchByLocale( $languageName );
472 $languageID = (int)$languageObj->attribute( 'id' );
473 }
474 $languageMask = $languageID;
475 if ( $alwaysAvailable )
476 $languageMask |= 1;
477
478 $path = eZURLAliasML::cleanURL( $path );
479 $elements = explode( '/', $path );
480
481 $db = eZDB::instance();
482 $parentID = 0;
483
484 // If the root ID is specified we will start the parent search from that
485 if ( $rootID !== false )
486 {
487 $parentID = $rootID;
488 }
489 $i = 0;
490 // Top element is handled separately.
491 $topElement = array_pop( $elements );
492 // Find correct parent, and create missing ones if necessary
493 $createdPath = array();
494 foreach ( $elements as $element )
495 {
496 $actionStr = $db->escapeString( $action );
497 if ( $cleanupElements )
498 $element = eZURLAliasML::convertToAlias( $element, 'noname' . (count($createdPath)+1) );
499 $elementStr = $db->escapeString( eZURLAliasML::strtolower( $element ) );
500
501 $query = "SELECT * FROM ezurlalias_ml WHERE text_md5 = " . eZURLAliasML::md5( $db, $elementStr, false ) . " AND parent = {$parentID}";
502 $rows = $db->arrayQuery( $query );
503 if ( count( $rows ) == 0 )
504 {
505 // Create a fake element to ensure we have a parent
506 $elementObj = eZURLAliasML::create( $element, "nop:", $parentID, 1 );
507 $elementObj->store();
508 $parentID = (int)$elementObj->attribute( 'id' );
509 }
510 else
511 {
512 $parentID = (int)$rows[0]['link'];
513 }
514 $createdPath[] = $element;
515
516 ++$i;
517 }
518 if ( $parentID != 0 )
519 {
520 $sql = "SELECT text, parent FROM ezurlalias_ml WHERE id = {$parentID}";
521 $rows = $db->arrayQuery( $sql );
522 if ( count( $rows ) > 0 )
523 {
524 // A special case. If the special entry with empty text is used as parent
525 // the parent must be adjust to 0 (ie. real top level).
526 if ( strlen( $rows[0]['text'] ) == 0 && $rows[0]['parent'] == 0 )
527 {
528 $createdPath = array();
529 $parentID = 0;
530 }
531 }
532 }
533
534 if ( !preg_match( "#^(.+):(.+)$#", $action, $matches ) )
535 {
536 return array( 'status' => self::ACTION_INVALID,
537 'error_message' => "The action value " . var_export( $action, true ) . " is invalid",
538 'error_number' => self::ACTION_INVALID,
539 'path' => null,
540 'element' => null );
541 }
542 $actionName = $matches[1];
543 $actionValue = $matches[2];
544 $existingElementID = null;
545 $alwaysMask = $alwaysAvailable ? 1 : 0;
546
547 $actionStr = $db->escapeString( $action );
548 $actionTypeStr = $db->escapeString( $actionName );
549
550 $createdElement = null;
551 if ( $linkID === false )
552 {
553 if ( $cleanupElements )
554 $topElement = eZURLAliasML::convertToAlias( $topElement, 'noname' . (count($createdPath)+1) );
555
556 $adjustName = false;
557 $curElementID = null;
558 $newElementID = null;
559 $newText = $topElement;
560 $uniqueCounter = 0;
561
562 // Loop until we a valid entry point, which means:
563 // 1. The entry does not exist yet, so create a new one
564 // 2. The entry exists but is re-usable (e.g. nop or same action)
565 // 3. The entry exists and cannot be re-used, instead the name is adjusted to be unique.
566 while ( true )
567 {
568 $newText = $topElement;
569 if ( $uniqueCounter > 0 )
570 $newText .= ($uniqueCounter + 1);
571 $textMD5 = eZURLAliasML::md5( $db, $newText );
572
573 $query = "SELECT * FROM ezurlalias_ml WHERE parent = $parentID AND text_md5 = {$textMD5}";
574 $rows = $db->arrayQuery( $query );
575 if ( count( $rows ) == 0 )
576 {
577 // No such entry, create a new one
578 break;
579 }
580
581 $row = $rows[0];
582 $curID = (int)$row['id'];
583 $curAction = $row['action'];
584 if ( $curAction == 'nop:' || $curAction == $action || $row['is_original'] == 0 )
585 {
586 // We can reuse the element so record the ID
587 $curElementID = $curID;
588 $newElementID = $curID;
589 break;
590 }
591
592 if ( !$autoAdjustName )
593 {
594 if ( $reportErrors )
595 eZDebug::writeError( "Tried to store path '{$path}' but the path already exists (ID: {$curID}) but with action '{$curAction}', the new action was '{$action}'" );
596 return array( 'status' => self::LINK_ALREADY_TAKEN,
597 'path' => $path,
598 'element' => null );
599 }
600 // Need to adjust name, re-iterate
601 ++$uniqueCounter;
602 }
603 $textEsc = $db->escapeString( $newText );
604
605 // See if there is already a node in the same level with the same action
606 if ( $newElementID === null )
607 {
608 $query = "SELECT * FROM ezurlalias_ml " .
609 "WHERE parent = $parentID AND action = '{$actionStr}' AND is_original = 1 AND is_alias = 0";
610 $rows = $db->arrayQuery( $query );
611 if ( count( $rows ) > 0 )
612 {
613 $newElementID = (int)$rows[0]['id'];
614 }
615 }
616
617 // Create or update the element
618 if ( $curElementID !== null )
619 {
620 // Check if an already existing entry at the same level exists, with a different id
621 // if so the id must be updated.
622 $query = "SELECT * FROM ezurlalias_ml " .
623 "WHERE parent = $parentID AND action = '{$actionStr}' AND is_original = 1 AND is_alias = 0";
624 $rows = $db->arrayQuery( $query );
625 if ( count( $rows ) > 0 )
626 {
627 $existingEntryId = (int)$rows[0]['id'];
628
629 if ( $existingEntryId != $curElementID )
630 {
631 // move history entry to the same id
632 $query = "UPDATE ezurlalias_ml SET id = {$existingEntryId} " .
633 "WHERE parent = $parentID AND text_md5 = {$textMD5}";
634 $res = $db->query( $query );
635 if ( !$res ) return eZURLAliasML::dbError( $db );
636 $curElementID = $existingEntryId;
637 }
638 }
639
640 $bitOr = $db->bitOr( $db->bitAnd( 'lang_mask', ~1 ), $languageMask );
641 // Note: The `text` field is updated too, this ensures case-changes are stored.
642 $query = "UPDATE ezurlalias_ml SET link = id, lang_mask = {$bitOr}, text = '{$textEsc}', action = '{$actionStr}', action_type = '{$actionTypeStr}', is_alias = 0, is_original = 1 " .
643 "WHERE parent = $parentID AND text_md5 = {$textMD5}";
644 $res = $db->query( $query );
645 if ( !$res ) return eZURLAliasML::dbError( $db );
646 $newElementID = $curElementID;
647 }
648 else
649 {
650 $element = new eZURLAliasML( array( 'id'=> $newElementID,
651 'link' => null,
652 'parent' => $parentID,
653 'text' => $newText,
654 'lang_mask' => $languageID | $alwaysMask,
655 'action' => $action ) );
656 $element->store();
657 $newElementID = (int)$element->attribute( 'id' );
658 $createdElement = $element;
659 }
660 $createdPath[] = $newText;
661
662 // OMS-urlalias-fix: We want to retain the lang_mask of url entries, but mark others as history elements is_original = 0
663 // Furthermore this change is not performed on custom alias entries.
664 $bitAnd = $db->bitAnd( 'lang_mask', $languageID );
665
666 // First we look at the entries to mark as history entries, if an entry comprise more languages, it must not be set as history element.
667 $query = "SELECT * FROM ezurlalias_ml " .
668 "WHERE action = '{$actionStr}' AND ({$bitAnd} > 0) AND is_original = 1 AND is_alias = 0 AND (parent != $parentID OR text_md5 != {$textMD5})";
669 $toBeUpdated = $db->arrayQuery( $query );
670
671 // 0. Check if the entry to be updated represents multiple languages:
672 // IF YES:
673 // 1. "Downgrade" existing entry, by removing the active translation's language id from the language_mask.
674 // IF NO:
675 // 1. Mark entry as a history entry
676
677 if ( count( $toBeUpdated ) > 0 )
678 {
679 $languageMask = $toBeUpdated[0]['lang_mask'];
680 if ( ( $languageMask & ~( $languageID | 1 ) ) != 0 )
681 {
682 // "Composite entry", downgrade current entry
683 $currentEntry = new eZURLAliasML( $toBeUpdated[0] );
684 $currentEntry->LangMask = (int)$currentEntry->LangMask & ~$languageID;
685 $currentEntry->store();
686 }
687 else
688 {
689 // Mark as history element.
690 $query = "UPDATE ezurlalias_ml SET is_original = 0 " .
691 "WHERE action = '{$actionStr}' AND ({$bitAnd} > 0) AND is_original = 1 AND is_alias = 0 AND (parent != $parentID OR text_md5 != {$textMD5})";
692 $res = $db->query( $query );
693 if ( !$res ) return eZURLAliasML::dbError( $db );
694 }
695 }
696
697 // OMS-urlalias-fix: instead entries without language we look at history elements with same action (and language)
698 // Look for other nodes with the same action and language
699 // if found make then link to the new entry
700 $bitAnd = $db->bitAnd( 'lang_mask', $languageID );
701 $query = "SELECT * FROM ezurlalias_ml " .
702 "WHERE action = '{$actionStr}' AND ({$bitAnd} > 0) AND is_original = 0 AND (parent != $parentID OR text_md5 != {$textMD5})";
703 $rows = $db->arrayQuery( $query );
704 foreach ( $rows as $row )
705 {
706 $idtmp = (int)$row['id'];
707 if ( $idtmp == $newElementID )
708 {
709 $idtmp = self::getNewID();
710 }
711 $parentIDTmp = (int)$row['parent'];
712 $textMD5Tmp = eZURLAliasML::md5( $db, $row['text'] );
713
714 // OMS-urlalias-fix: We do not touch the lang_mask here
715 $res = $db->query( "UPDATE ezurlalias_ml SET id = {$idtmp}, link = {$newElementID}, is_alias = 0, is_original = 0 " .
716 "WHERE parent = {$parentIDTmp} AND text_md5 = {$textMD5Tmp}" );
717 if ( !$res ) return eZURLAliasML::dbError( $db );
718 }
719 $res = $db->query( $query );
720 if ( !$res ) return eZURLAliasML::dbError( $db );
721
722 // Look for other nodes which is a link for the current action
723 // if found make then link to the new entry
724 // OMS-urlalias-fix: We only want to update the links of entries within the same language.
725 // Also, only to be applied on normal entries, not custom aliases
726 $bitAnd = $db->bitAnd( 'lang_mask', $languageID );
727 $query = "UPDATE ezurlalias_ml SET link = {$newElementID}, is_alias = 0, is_original = 0 " .
728 "WHERE action = '{$actionStr}' AND is_original = 0 AND is_alias = 0 AND ({$bitAnd} > 0) AND (parent != $parentID OR text_md5 != {$textMD5})";
729 $res = $db->query( $query );
730 if ( !$res ) return eZURLAliasML::dbError( $db );
731
732
733 // Move children from old node to the new node
734 // Conflicts:
735 // New | Old | Action
736 // -------------------------------
737 // Element | Link | Delete old
738 // Element | Element | Will not happen, if so delete old
739 // Element | Other | Reparent with new name
740 // Element | nop | Delete old
741 // Link | Link | Delete old
742 // Link | Element | Delete new, reparent
743 // Link | Other | Delete new, reparent
744 // Link | nop | Delete old
745 // nop | Link | Delete new, reparent
746 // nop | Element | Delete new, reparent
747 // nop | nop | Delete old
748
749 // TODO: Handle all conflict cases, for now only the `Delete old, reparent` action is done
750
751 // OMS-urlalias-fix: We are only updating child nodes within the same language,
752 // and only for real system-generated url aliases. Custom aliases are left alone.
753 $bitAnd = $db->bitAnd( 'lang_mask', $languageID );
754 $query = "SELECT id FROM ezurlalias_ml " .
755 "WHERE action = '{$actionStr}' AND is_alias = 0 AND (parent != $parentID OR text_md5 != {$textMD5})";
756 $rows = $db->arrayQuery( $query );
757 foreach ( $rows as $row )
758 {
759 $oldParentID = (int)$row['id'];
760 $query = "UPDATE ezurlalias_ml SET parent = {$newElementID} " .
761 "WHERE parent = {$oldParentID} AND ({$bitAnd} > 0)";
762 $res = $db->query( $query );
763 if ( !$res ) return eZURLAliasML::dbError( $db );
764 }
765 }
766 else
767 {
768 // Check the link ID
769 if ( $linkID !== true )
770 {
771 $linkID = (int)$linkID;
772 // Step 1, find existing ID
773 $query = "SELECT * FROM ezurlalias_ml WHERE id = '{$linkID}'";
774 $rows = $db->arrayQuery( $query );
775 // Some sanity checking
776 if ( count( $rows ) == 0 )
777 {
778 if ( $reportErrors )
779 eZDebug::writeError( "The link ID $linkID does not exist, cannot create the link", __METHOD__ );
780 return array( 'status' => eZURLAliasML::LINK_ID_NOT_FOUND );
781 }
782 if ( $rows[0]['action'] != $action )
783 {
784 if ( $reportErrors )
785 eZDebug::writeError( "The link ID $linkID uses a different action ({$rows[0]['action']}) than the requested action ({$action}) for the link, cannot create the link", __METHOD__ );
786 return array( 'status' => eZURLAliasML::LINK_ID_WRONG_ACTION );
787 }
788 // If the element which is pointed to is a link, then grab the link id from that instead
789 if ( $rows[0]['link'] != $rows[0]['id'] )
790 {
791 $linkID = (int)$rows[0]['link'];
792 }
793 }
794 else
795 {
796 $linkID = null;
797 }
798
799 if ( $cleanupElements )
800 $topElement = eZURLAliasML::convertToAlias( $topElement, 'noname' . (count($createdPath)+1) );
801
802 $adjustName = false;
803 $curElementID = null;
804 $newText = $topElement;
805 $uniqueCounter = 0;
806 $rows = null; // Will be filled in by the while loop
807
808 // Loop until we a valid entry point, which means:
809 // 1. The entry does not exist yet, so create a new one
810 // 2. The entry exists but is re-usable (e.g. nop or same action)
811 // 3. The entry exists and cannot be re-used, instead the name is adjusted to be unique.
812 while ( true )
813 {
814 $newText = $topElement;
815 if ( $uniqueCounter > 0 )
816 $newText .= ($uniqueCounter + 1);
817 $textMD5 = eZURLAliasML::md5( $db, $newText );
818
819 $query = "SELECT * FROM ezurlalias_ml WHERE parent = $parentID AND text_md5 = {$textMD5}";
820 $rows = $db->arrayQuery( $query );
821 if ( count( $rows ) == 0 )
822 {
823 // No such entry, create a new one
824 break;
825 }
826
827 $row = $rows[0];
828 $curID = (int)$row['id'];
829 $curLink = (int)$row['link'];
830 $curAction = $row['action'];
831 if ( $curAction == $action )
832 {
833 // If the current node is the same action and is not a link we
834 // cannot replace it with a link node.
835 if ( $curID != $curLink )
836 {
837 // We can reuse the element so record the ID
838 $curElementID = $curID;
839 break;
840 }
841
842 // If the current node is the same action, but the language is different
843 // (enables adding the same URL alias for other languages)
844 if ( !( (int)$row['lang_mask'] & $languageID ) )
845 {
846 // We can reuse the element so record the ID
847 $curElementID = $curID;
848 break;
849 }
850 }
851 else if ( $curAction == 'nop:' || $row['is_original'] == 0 )
852 {
853 // We can reuse the element so record the ID
854 $curElementID = $curID;
855 break;
856 }
857
858 if ( !$autoAdjustName )
859 {
860 if ( $reportErrors )
861 eZDebug::writeError( "Tried to store path '{$path}' but the path already exists (ID: {$curID}) but with action '{$curAction}', the new action was '{$action}'" );
862 return array( 'status' => self::LINK_ALREADY_TAKEN,
863 'path' => $path,
864 'element' => null );
865 }
866 // Need to adjust name, re-iterate
867 ++$uniqueCounter;
868 }
869 $textEsc = $db->escapeString( $newText );
870
871 // Create or update the element
872 if ( $curElementID !== null )
873 {
874 $element = new eZURLAliasML( $rows[0] ); // $rows is from the while loop
875 $element->LangMask |= $languageID | $alwaysMask;
876 $element->IsAlias = 1;
877 $element->Action = $action;
878 // Note: The `text` field is updated too, this ensures case-changes are stored.
879 $element->Text = $newText;
880 $element->TextMD5 = null;
881 $element->ActionType = null;
882 $element->Link = null;
883 }
884 else
885 {
886 $element = new eZURLAliasML( array( 'id'=> null,
887 'link' => null,
888 'parent' => $parentID,
889 'text' => $newText,
890 'lang_mask' => $languageID | $alwaysMask,
891 'action' => $action,
892 'is_alias' => 1 ) );
893 }
894 $element->AliasRedirects = $aliasRedirects ? 1 : 0;
895 $element->store();
896 $createdPath[] = $topElement;
897 $createdElement = $element;
898 }
899 return array( 'status' => true,
900 'path' => join( "/", $createdPath ),
901 'element' => $createdElement );
902 }
903
911 static private function dbError( $db )
912 {
913 return array( 'status' => self::DB_ERROR,
914 'error_message' => $db->errorMessage(),
915 'error_number' => $db->errorNumber(),
916 'path' => null,
917 'element' => null );
918 }
919
967 static public function fetchByAction( $actionName, $actionValue, $maskLanguages = false, $onlyPrioritized = false, $includeRedirections = false )
968 {
969 $action = $actionName . ":" . $actionValue;
970 $db = eZDB::instance();
971 $actionStr = $db->escapeString( $action );
972 $langMask = '';
973 if ( $maskLanguages === true )
974 {
975 $langMask = "(" . trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) ) . ") AND ";
976 }
977 else if ( is_string( $maskLanguages ) || is_array( $maskLanguages ) )
978 {
979 // maskByLocale can support array input, here we only want one item.
980 $mask = eZContentLanguage::maskByLocale( (array)$maskLanguages );
981 $langFilter = $db->bitAnd( 'lang_mask', $mask );
982 $langMask = "({$langFilter} > 0) AND";
983 }
984 $query = "SELECT * FROM ezurlalias_ml WHERE $langMask action = '$actionStr'";
985 if ( !$includeRedirections )
986 {
987 $query .= " AND is_original = 1 AND is_alias = 0";
988 }
989
990 $rows = $db->arrayQuery( $query );
991 if ( count( $rows ) == 0 )
992 return array();
993 $rows = eZURLAliasML::filterRows( $rows, $onlyPrioritized );
994 $objectList = eZPersistentObject::handleRows( $rows, 'eZURLAliasML', true );
995 return $objectList;
996 }
997
1049 static public function fetchByParentID( $id, $maskLanguages = false, $onlyPrioritized = false, $includeRedirections = true )
1050 {
1051 $db = eZDB::instance();
1052 $id = (int)$id;
1053 $langMask = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
1054 $redirSQL = '';
1055 if ( !$includeRedirections )
1056 {
1057 $redirSQL = " AND is_original = 1";
1058 }
1059 $langMask = '';
1060 if ( $maskLanguages )
1061 {
1062 $langMask = "(" . trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) ) . ") AND ";
1063 }
1064 $query = "SELECT * FROM ezurlalias_ml WHERE $langMask parent = {$id} $redirSQL";
1065 $rows = $db->arrayQuery( $query );
1066 $rows = eZURLAliasML::filterRows( $rows, $onlyPrioritized );
1067 return eZPersistentObject::handleRows( $rows, 'eZURLAliasML', true );
1068 }
1069
1103 static public function fetchPathByActionList( $actionName, $actionValues, $locale = null )
1104 {
1105 if ( !is_array( $actionValues ) || count( $actionValues ) == 0 )
1106 {
1107 eZDebug::writeError( "Action values array must not be empty", __METHOD__ );
1108 return null;
1109 }
1110 $db = eZDB::instance();
1111 $actionList = array();
1112 foreach ( $actionValues as $i => $value )
1113 {
1114 $actionList[] = "'" . $db->escapeString( $actionName . ":" . $value ) . "'";
1115 }
1116 $actionStr = join( ", ", $actionList );
1117 $filterSQL = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
1118 $query = "SELECT id, parent, lang_mask, text, action FROM ezurlalias_ml WHERE ( {$filterSQL} ) AND action in ( {$actionStr} ) AND is_original = 1 AND is_alias=0";
1119 $rows = $db->arrayQuery( $query );
1120 $objects = eZContentObject::fetchByNodeID( $actionValues );
1121 $actionMap = array();
1122 foreach ( $rows as $row )
1123 {
1124 $action = $row['action'];
1125 if ( !isset( $actionMap[$action] ) )
1126 $actionMap[$action] = array();
1127 $actionMap[$action][] = $row;
1128 }
1129
1130 if ( $locale !== null && is_string( $locale ) && !empty( $locale ) )
1131 {
1132 $selectedLanguage = eZContentLanguage::fetchByLocale( $locale );
1133 $prioritizedLanguages = eZContentLanguage::prioritizedLanguages();
1134 // Add $selectedLanguage on top of $prioritizedLanguages to take it into account with the highest priority
1135 if ( $selectedLanguage instanceof eZContentLanguage )
1136 array_unshift( $prioritizedLanguages, $selectedLanguage );
1137 }
1138 else
1139 {
1140 $prioritizedLanguages = eZContentLanguage::prioritizedLanguages();
1141 }
1142
1143 $path = array();
1144 $lastID = false;
1145 foreach ( $actionValues as $actionValue )
1146 {
1147 $action = $actionName . ":" . $actionValue;
1148 if ( !isset( $actionMap[$action] ) )
1149 {
1150 // eZDebug::writeError( "The action '{$action}' was not found in the database for the current language language filter, cannot calculate path." );
1151 return null;
1152 }
1153 $actionRows = $actionMap[$action];
1154 $defaultRow = null;
1155 foreach( $prioritizedLanguages as $language )
1156 {
1157 foreach ( $actionRows as $row )
1158 {
1159 $langMask = (int)$row['lang_mask'];
1160 $wantedMask = (int)$language->attribute( 'id' );
1161 if ( ( $wantedMask & $langMask ) > 0 )
1162 {
1163 $defaultRow = $row;
1164 break 2;
1165 }
1166 // If the 'always available' bit is set AND it corresponds to the main language, then choose it as the default
1167 if ( $langMask & 1 && $objects[$actionValue]->attribute( 'initial_language_id' ) & $langMask )
1168 {
1169 $defaultRow = $row;
1170 }
1171 }
1172 }
1173 if ( $defaultRow )
1174 {
1175 $id = (int)$defaultRow['id'];
1176 $paren = (int)$defaultRow['parent'];
1177
1178 // If the parent is 0 it means the element is at the top, ie. reset the path and lastID
1179 if ( $paren == 0 )
1180 {
1181 $lastID = false;
1182 $path = array();
1183 }
1184
1185 $path[] = $defaultRow['text'];
1186
1187 // Check for a valid path
1188 if ( $lastID !== false && $lastID != $paren )
1189 {
1190 eZDebug::writeError( "The parent ID $paren of element with ID $id does not point to the last entry which had ID $lastID, incorrect path would be calculated, aborting" );
1191 return null;
1192 }
1193 $lastID = $id;
1194 }
1195 else
1196 {
1197 // No row was found
1198 eZDebug::writeError( "Fatal error, no row was chosen for action " . $actionName . ":" . $actionValue );
1199 return null;
1200 }
1201 }
1202 return join( "/", $path );
1203 }
1204
1253 static public function fetchByPath( $uriString, $glob = false )
1254 {
1255 $uriString = eZURLAliasML::cleanURL( $uriString );
1256
1257 $db = eZDB::instance();
1258 if ( $uriString == '' && $glob !== false )
1259 $elements = array();
1260 else
1261 $elements = explode( '/', $uriString );
1262 $len = count( $elements );
1263 $i = 0;
1264 $selects = array();
1265 $tables = array();
1266 $conds = array();
1267 $prevTable = false;
1268 foreach ( $elements as $element )
1269 {
1270 $table = "e" . $i;
1271 $langMask = trim( eZContentLanguage::languagesSQLFilter( $table, 'lang_mask' ) );
1272
1273 if ( $glob === false && ($i == $len - 1) )
1274 $selects[] = eZURLAliasML::generateFullSelect( $table );
1275 else
1276 $selects[] = eZURLAliasML::generateSelect( $table, $i, $len );
1277 $tables[] = "ezurlalias_ml " . $table;
1278 $conds[] = eZURLAliasML::generateCond( $table, $prevTable, $i, $langMask, $element );
1279 $prevTable = $table;
1280 ++$i;
1281 }
1282 if ( $glob !== false )
1283 {
1284 ++$len;
1285 $table = "e" . $i;
1286 $langMask = trim( eZContentLanguage::languagesSQLFilter( $table, 'lang_mask' ) );
1287
1288 $selects[] = eZURLAliasML::generateFullSelect( $table );
1289 $tables[] = "ezurlalias_ml " . $table;
1290 $conds[] = eZURLAliasML::generateGlobCond( $table, $prevTable, $i, $langMask, $glob );
1291 $prevTable = $table;
1292 ++$i;
1293 }
1294 $elementOffset = $i - 1;
1295 $query = "SELECT DISTINCT " . join( ", ", $selects ) . " FROM " . join( ", ", $tables ) . " WHERE " . join( " AND ", $conds );
1296
1297 $pathRows = $db->arrayQuery( $query );
1298 $elements = array();
1299 if ( count( $pathRows ) > 0 )
1300 {
1301 foreach ( $pathRows as $pathRow )
1302 {
1303 $redirectLink = false;
1304 $table = "e" . $elementOffset;
1305 $element = array( 'id' => $pathRow[$table . "_id"],
1306 'parent' => $pathRow[$table . "_parent"],
1307 'lang_mask' => $pathRow[$table . "_lang_mask"],
1308 'text' => $pathRow[$table . "_text"],
1309 'action' => $pathRow[$table . "_action"],
1310 'link' => $pathRow[$table . "_link"] );
1311 $path = array();
1312 $lastID = false;
1313 for ( $i = 0; $i < $len; ++$i )
1314 {
1315 $table = "e" . $i;
1316 $id = $pathRow[$table . "_id"];
1317 $link = $pathRow[$table . "_link"];
1318 $path[] = $pathRow[$table . "_text"];
1319 if ( $link != $id )
1320 {
1321 // Mark the redirect link
1322 $redirectLink = $link;
1323 $redirectOffset = $i;
1324 }
1325 $lastID = $link;
1326 }
1327 if ( $redirectLink )
1328 {
1329 $newLinkID = $redirectLink;
1330 // Resolve new links until a real element is found.
1331 // TODO: Add max redirection count?
1332 while ( $newLinkID )
1333 {
1334 $query = "SELECT id, parent, lang_mask, text, link FROM ezurlalias_ml WHERE id={$newLinkID}";
1335 $rows = $db->arrayQuery( $query );
1336 if ( count( $rows ) == 0 )
1337 {
1338 return false;
1339 }
1340 $newLinkID = false;
1341 if ( $rows[0]['id'] != $rows[0]['link'] )
1342 $newLinkID = (int)$rows[0]['link'];
1343 }
1344 $id = (int)$newLinkID;
1345 $path = array();
1346
1347 // Fetch path 'text' elements of correct parent path
1348 while ( $id != 0 )
1349 {
1350 $query = "SELECT parent, lang_mask, text FROM ezurlalias_ml WHERE id={$id}";
1351 $rows = $db->arrayQuery( $query );
1352 if ( count( $rows ) == 0 )
1353 {
1354 break;
1355 }
1356 $result = eZURLAliasML::choosePrioritizedRow( $rows );
1357 if ( !$result )
1358 {
1359 $result = $rows[0];
1360 }
1361 $id = (int)$result['parent'];
1362 array_unshift( $path, $result['text'] );
1363 }
1364 // Fill in end of path elements
1365 for ( $i = $redirectOffset; $i < $len; ++$i )
1366 {
1367 $table = "e" . $i;
1368 $path[] = $pathRow[$table . "_text"];
1369 }
1370 }
1371 $element['path'] = implode( '/', $path );
1372 $elements[] = $element;
1373 }
1374 }
1375 $rows = array();
1376 $ids = array();
1377 // Discard duplicates
1378 foreach ( $elements as $element )
1379 {
1380 $id = (int)$element['id'];
1381 if ( isset( $ids[$id] ) )
1382 continue;
1383 $ids[$id] = true;
1384 $rows[] = $element;
1385 }
1386 $objectList = eZPersistentObject::handleRows( $rows, 'eZURLAliasML', true );
1387 return $objectList;
1388 }
1389
1396 static public function fetchNodeIDByPath( $uriString, $glob = false )
1397 {
1398 $nodeID = false;
1399
1400 $urlAliasMLList = eZURLAliasML::fetchByPath( $uriString, $glob );
1401 if ( is_array( $urlAliasMLList ) && count( $urlAliasMLList ) > 0 )
1402 $nodeID = eZURLAliasML::nodeIDFromAction( $urlAliasMLList[0]->Action );
1403
1404 return $nodeID;
1405 }
1406
1491 static public function translate( &$uri, $reverse = false )
1492 {
1493 if ( $uri instanceof eZURI )
1494 {
1495 $uriString = $uri->elements();
1496 }
1497 else
1498 {
1499 $uriString = $uri;
1500 }
1501 $uriString = eZURLAliasML::cleanURL( $uriString );
1502 $internalURIString = $uriString;
1503 $originalURIString = $uriString;
1504
1505 if ( $reverse )
1506 {
1507 return eZURLAliasML::reverseTranslate( $uri, $uriString, $internalURIString );
1508 }
1509
1510 $ini = eZINI::instance();
1511
1512 $prefixAdded = false;
1513 $prefix = self::getPathPrefix();
1514
1515 if ( $prefix )
1516 {
1517 $escapedPrefix = preg_quote( $prefix, '#' );
1518 // Only prepend the path prefix if it's not already the first element of the url.
1519 if ( !preg_match( "#^$escapedPrefix(/.*)?$#i", $uriString ) )
1520 {
1521 $exclude = $ini->hasVariable( 'SiteAccessSettings', 'PathPrefixExclude' )
1522 ? $ini->variable( 'SiteAccessSettings', 'PathPrefixExclude' )
1523 : false;
1524 $breakInternalURI = false;
1525 foreach ( $exclude as $item )
1526 {
1527 $escapedItem = preg_quote( $item, '#' );
1528 if ( preg_match( "#^$escapedItem(/.*)?$#i", $uriString ) )
1529 {
1530 $breakInternalURI = true;
1531 break;
1532 }
1533 }
1534
1535 if ( !$breakInternalURI )
1536 {
1537 $internalURIString = $prefix . '/' . $uriString;
1538 $prefixAdded = true;
1539 }
1540 }
1541 }
1542
1543 $db = eZDB::instance();
1544 $elements = explode( '/', $internalURIString );
1545 $len = count( $elements );
1546
1547 $i = 0;
1548 $selects = array();
1549 $tables = array();
1550 $conds = array();
1551 foreach ( $elements as $element )
1552 {
1553 $table = "e" . $i;
1554
1555 $selectString = "{$table}.id AS {$table}_id, ";
1556 $selectString .= "{$table}.link AS {$table}_link, ";
1557 $selectString .= "{$table}.text AS {$table}_text, ";
1558 $selectString .= "{$table}.text_md5 AS {$table}_text_md5, ";
1559 $selectString .= "{$table}.is_alias AS {$table}_is_alias, ";
1560
1561 if ( $i == $len - 1 )
1562 $selectString .= "{$table}.action AS {$table}_action, ";
1563
1564 $selectString .= "{$table}.alias_redirects AS {$table}_alias_redirects";
1565 $selects[] = $selectString;
1566
1567 $tables[] = "ezurlalias_ml " . $table;
1568 $langMask = trim( eZContentLanguage::languagesSQLFilter( $table, 'lang_mask' ) );
1569 if ( $i == 0 )
1570 {
1571 $conds[] = "{$table}.parent = 0 AND ({$langMask}) AND {$table}.text_md5 = " . eZURLAliasML::md5( $db, $element );
1572 }
1573 else
1574 {
1575 $conds[] = "{$table}.parent = {$prevTable}.link AND ({$langMask}) AND {$table}.text_md5 = " . eZURLAliasML::md5( $db, $element );
1576 }
1577 $prevTable = $table;
1578 ++$i;
1579 }
1580
1581 $query = "SELECT " . join( ", ", $selects ) . " FROM " . join( ", ", $tables ) . " WHERE " . join( " AND ", $conds );
1582 $return = false;
1583 $urlAliasArray = $db->arrayQuery( $query, array( 'limit' => 1 ) );
1584 if ( count( $urlAliasArray ) > 0 )
1585 {
1586 $pathRow = $urlAliasArray[0];
1587 $l = count( $pathRow );
1588 $redirectLink = false;
1589 $redirectAction = false;
1590 $lastID = false;
1591 $action = false;
1592 $verifiedPath = array();
1593 $doRedirect = false;
1594
1595 for ( $i = 0; $i < $len; ++$i )
1596 {
1597 $table = "e" . $i;
1598 $id = $pathRow[$table . "_id"];
1599 $link = $pathRow[$table . "_link"];
1600 $text = $pathRow[$table . "_text"];
1601 $isAlias = $pathRow[$table . '_is_alias'];
1602 $aliasRedirects = $pathRow[$table . '_alias_redirects'];
1603 $verifiedPath[] = $text;
1604 if ( $i == $len - 1 )
1605 {
1606 $action = $pathRow[$table . "_action"];
1607 }
1608 if ( $link != $id )
1609 {
1610 $doRedirect = true;
1611 }
1612 else if ( $isAlias && $action !== false )
1613 {
1614 if ( $aliasRedirects )
1615 {
1616 // If the entry is an alias and we have an action we redirect to the original
1617 // url of that action.
1618 $redirectAction = $action;
1619 $doRedirect = true;
1620 }
1621 }
1622 $lastID = $link;
1623 }
1624
1625 if ( !$doRedirect )
1626 {
1627 $verifiedPathString = implode( '/', $verifiedPath );
1628 // Check for case difference
1629 if ( $prefixAdded )
1630 {
1631 if ( strcmp( $originalURIString, substr( $verifiedPathString, strlen( $prefix ) + 1 ) ) != 0 )
1632 {
1633 $doRedirect = true;
1634 }
1635 }
1636 else if ( strcmp( $verifiedPathString, $internalURIString ) != 0 )
1637 {
1638 $doRedirect = true;
1639 }
1640 }
1641
1642 if ( preg_match( "#^module:(.+)$#", $action, $matches ) and $doRedirect )
1643 {
1644 $uriString = 'error/301';
1645 $return = $matches[1];
1646 }
1647 else if ( $doRedirect )
1648 {
1649 if ( $redirectAction !== false )
1650 {
1651 $query = "SELECT id FROM ezurlalias_ml WHERE action = '" . $db->escapeString( $action ) . "' AND is_original = 1 AND is_alias = 0";
1652 $rows = $db->arrayQuery( $query );
1653 if ( count( $rows ) > 0 )
1654 {
1655 $id = (int)$rows[0]['id'];
1656 }
1657 else
1658 {
1659 $id = false;
1660 $uriString = 'error/301';
1661 $return = join( "/", $pathData );
1662 }
1663 }
1664 else
1665 {
1666 $id = (int)$lastID;
1667 }
1668
1669 if ( $id !== false )
1670 {
1671 $pathData = array();
1672 // Figure out the correct path by iterating down the parents until we have all
1673 // elements figured out.
1674
1675 while ( $id != 0 )
1676 {
1677 $query = "SELECT parent, lang_mask, text FROM ezurlalias_ml WHERE id={$id}";
1678 $rows = $db->arrayQuery( $query );
1679 if ( count( $rows ) == 0 )
1680 {
1681 break;
1682 }
1683 $result = eZURLAliasML::choosePrioritizedRow( $rows );
1684 if ( !$result )
1685 {
1686 $result = $rows[0];
1687 }
1688 $id = (int)$result['parent'];
1689 array_unshift( $pathData, $result['text'] );
1690 }
1691 $uriString = 'error/301';
1692 $return = join( "/", $pathData );
1693 }
1694
1695 // Remove prefix of redirect uri if needed
1696 if ( $prefix && is_string( $return ) )
1697 {
1698 if ( strncasecmp( $return, $prefix . '/', strlen( $prefix ) + 1 ) == 0 )
1699 {
1700 $return = substr( $return, strlen( $prefix ) + 1 );
1701 }
1702 }
1703 }
1704 else
1705 {
1706 // See http://issues.ez.no/19062
1707 // If $uriString matches a nop action, we need to check if we also match a wildcard
1708 // since we might want to translate it.
1709 // Default action for nop actions is to display the root node "/" (see eZURLAliasML::actionToURL())
1710 if ( strpos( $action, 'nop') !== false && eZURLWildcard::wildcardExists( $uriString ) )
1711 {
1712 $return = false;
1713 }
1714 else
1715 {
1716 $uriString = eZURLAliasML::actionToUrl( $action );
1717 $return = true;
1718 }
1719
1720 }
1721
1722 if ( $uri instanceof eZURI )
1723 {
1724 $uri->setURIString( $uriString, false );
1725 }
1726 else
1727 {
1728 $uri = $uriString;
1729 }
1730 }
1731
1732 return $return;
1733 }
1734
1740 static public function reverseTranslate( &$uri, $uriString, $internalURIString )
1741 {
1742 $db = eZDB::instance();
1743
1744 $action = eZURLAliasML::urlToAction( $internalURIString );
1745 if ( $action !== false )
1746 {
1747 $langMask = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
1748 $actionStr = $db->escapeString( $action );
1749 $query = "SELECT id, parent, lang_mask, text, action FROM ezurlalias_ml WHERE ($langMask) AND action='{$actionStr}' AND is_original = 1 AND is_alias = 0";
1750 $rows = $db->arrayQuery( $query );
1751 $path = array();
1752 $count = count( $rows );
1753 if ( $count != 0 )
1754 {
1755 $row = eZURLAliasML::choosePrioritizedRow( $rows );
1756 if ( $row === false )
1757 {
1758 $row = $rows[0];
1759 }
1760 $paren = (int)$row['parent'];
1761 $path[] = $row['text'];
1762 // We have the parent so now do an iterative lookup until we have the top element
1763 while ( $paren != 0 )
1764 {
1765 $query = "SELECT id, parent, lang_mask, text FROM ezurlalias_ml WHERE ($langMask) AND id=$paren AND is_original = 1 AND is_alias = 0";
1766 $rows = $db->arrayQuery( $query );
1767 $count = count( $rows );
1768 if ( $count != 0 )
1769 {
1770 $row = eZURLAliasML::choosePrioritizedRow( $rows );
1771 if ( $row === false )
1772 {
1773 $row = $rows[0];
1774 }
1775 $paren = (int)$row['parent'];
1776 array_unshift( $path, $row['text'] );
1777 }
1778 else
1779 {
1780 eZDebug::writeError( "Lookup of parent ID $paren failed, cannot perform reverse lookup of alias." );
1781 return false;
1782 }
1783 }
1784 $uriString = join( '/', $path );
1785 $uriString = self::removePathPrefixFromURI( $uriString );
1786 if ( $uri instanceof eZURI )
1787 {
1788 $uri->setURIString( $uriString, false );
1789 }
1790 else
1791 {
1792 $uri = $uriString;
1793 }
1794 return true;
1795 }
1796 else
1797 {
1798 return false;
1799 }
1800 }
1801 return false;
1802 }
1803
1809 static public function getPathPrefix()
1810 {
1811 $ini = eZINI::instance();
1812
1813 return $ini->hasVariable( 'SiteAccessSettings', 'PathPrefix' ) &&
1814 $ini->variable( 'SiteAccessSettings', 'PathPrefix' ) != ''
1815 ? eZURLAliasML::cleanURL( $ini->variable( 'SiteAccessSettings', 'PathPrefix' ) )
1816 : false;
1817 }
1818
1824 static public function removePathPrefixFromURI($uriString)
1825 {
1826 $ini = eZINI::instance();
1827
1828 $prefix = self::getPathPrefix();
1829 if ( !$prefix )
1830 {
1831 return $uriString;
1832 }
1833
1834 $exclude = $ini->hasVariable( 'SiteAccessSettings', 'PathPrefixExclude' )
1835 ? $ini->variable( 'SiteAccessSettings', 'PathPrefixExclude' )
1836 : false;
1837 foreach ( $exclude as $item )
1838 {
1839 $escapedItem = preg_quote( $item, '#' );
1840 if ( preg_match( "#^$escapedItem(/.*)?$#i", $uriString ) )
1841 {
1842 return $uriString;
1843 }
1844 }
1845
1846 $escapedPrefix = preg_quote( $prefix, '#' );
1847 $modifiedUriString = preg_replace( "#^$escapedPrefix/?#i", '', $uriString );
1848 return $modifiedUriString === null ? $uriString : $modifiedUriString;
1849 }
1850
1857 static public function urlTranslationEnabledByUri( eZURI $uri )
1858 {
1859 if ( $uri->isEmpty() )
1860 return false;
1861
1862 $ini = eZINI::instance();
1863 if ( $ini->variable( 'URLTranslator', 'Translation' ) === 'enabled' )
1864 {
1865 if ( $ini->variable( 'URLTranslator', 'TranslatableSystemUrls' ) === 'disabled' )
1866 {
1867 $moduleName = $uri->element( 0 );
1868 $moduleINI = eZINI::instance( 'module.ini' );
1869 $moduleList = $moduleINI->variable( 'ModuleSettings', 'ModuleList' );
1870 if ( in_array( $moduleName, $moduleList, true ) )
1871 return false;
1872 }
1873 return true;
1874 }
1875 return false;
1876 }
1877
1888 static public function findUniqueText( $parentElementID, $text, $action, $linkCheck = false, $languageID = false )
1889 {
1890 $db = eZDB::instance();
1891 $uniqueNumber = 0;
1892 // If there is no parent we need to check against reserved words
1893 if ( $parentElementID == 0 )
1894 {
1895 $moduleINI = eZINI::instance( 'module.ini' );
1896 $reserved = $moduleINI->variable( 'ModuleSettings', 'ModuleList' );
1897 foreach ( $reserved as $res )
1898 {
1899 if ( strcasecmp( $text, $res ) == 0 )
1900 {
1901 // The name is a reserved word so it needs to be changed
1902 ++$uniqueNumber;
1903 break;
1904 }
1905 }
1906 }
1907 $suffix = '';
1908 if ( $uniqueNumber )
1909 $suffix = $uniqueNumber + 1;
1910
1911 $actionSQL = '';
1912 if ( strlen( $action ) > 0 )
1913 {
1914 $actionEsc = $db->escapeString( $action );
1915 $actionSQL = "AND action != '$actionEsc'";
1916 }
1917 $languageSQL = "";
1918 if ( $languageID !== false )
1919 {
1920 $languageSQL = "AND " . $db->bitAnd( 'lang_mask', $languageID ) . ' > 0';
1921 }
1922 // Loop until we find a unique name
1923 while ( true )
1924 {
1925 $textEsc = eZURLAliasML::md5( $db, $text . $suffix );
1926 $query = "SELECT * FROM ezurlalias_ml WHERE parent = $parentElementID $actionSQL $languageSQL AND text_md5 = $textEsc";
1927 if ( !$linkCheck )
1928 {
1929 $query .= " AND is_original = 1";
1930 }
1931 if ( $db->databaseName() === 'mysql' )
1932 {
1933 $query .= ' LOCK IN SHARE MODE';
1934 }
1935 $rows = $db->arrayQuery( $query );
1936 if ( count( $rows ) == 0 )
1937 {
1938 return $text . $suffix;
1939 }
1940
1941 ++$uniqueNumber;
1942 $suffix = $uniqueNumber + 1;
1943 }
1944 }
1945
1951 static public function setLangMaskAlwaysAvailable( $langID, $actionName, $actionValue )
1952 {
1953 if ( !$actionName )
1954 {
1955 eZDebug::writeError( "ActionName value must not be empty", __METHOD__ );
1956 return null;
1957 }
1958 $db = eZDB::instance();
1959 if ( is_array( $actionName ) )
1960 {
1961 $actions = array();
1962 foreach ( $actionName as $actionItem )
1963 {
1964 $action = $actionItem[0] . ":" . $actionItem[1];
1965 $actions[] = "'" . $db->escapeString( $action ) . "'";
1966 }
1967 $actionSql = "action in (" . implode( ', ', $actions ) . ")";
1968 }
1969 else
1970 {
1971 $action = $actionName . ":" . $actionValue;
1972 $actionSql = "action = '" . $db->escapeString( $action ) . "'";
1973 }
1974 if ( $langID !== false )
1975 {
1976 // Set the 0 bit for chosen language
1977 $bitOp = $db->bitOr( 'lang_mask', 1 );
1978 $langWhere = ' AND ' . $db->bitAnd( 'lang_mask' , (int)$langID ) . ' > 0';
1979
1980 $query = "UPDATE ezurlalias_ml SET lang_mask = $bitOp WHERE $actionSql $langWhere";
1981 $db->query( $query );
1982
1983 // Clear the 0 bit for all other languages
1984 $bitOp = $db->bitAnd( 'lang_mask', ~1 );
1985 $langWhere = ' AND ' . $db->bitAnd( 'lang_mask' , (int)$langID ) . ' = 0';
1986
1987 $query = "UPDATE ezurlalias_ml SET lang_mask = $bitOp WHERE $actionSql $langWhere";
1988 $db->query( $query );
1989 }
1990 else
1991 {
1992 $bitOp = $db->bitAnd( 'lang_mask', ~1 );
1993 $query = "UPDATE ezurlalias_ml SET lang_mask = $bitOp WHERE $actionSql";
1994 $db->query( $query );
1995 }
1996 }
1997
2003 static public function choosePrioritizedRow( $rows )
2004 {
2005 $result = false;
2006 $score = 0;
2007 foreach ( $rows as $row )
2008 {
2009 if ( $result )
2010 {
2011 $newScore = eZURLAliasML::languageScore( $row['lang_mask'] );
2012 if ( $newScore > $score )
2013 {
2014 $result = $row;
2015 $score = $newScore;
2016 }
2017 }
2018 else
2019 {
2020 $result = $row;
2021 $score = eZURLAliasML::languageScore( $row['lang_mask'] );
2022 }
2023 }
2024
2025 // If score is still 0, this means that the objects languages don't
2026 // match the INI settings, and these should be fix according to the doc.
2027 if ( $score == 0 )
2028 {
2029 eZDebug::writeWarning(
2030 "None of the available languages are prioritized in the SiteLanguageList setting. An arbitrary language will be used.",
2031 __METHOD__ );
2032 }
2033
2034 return $result;
2035 }
2036
2044 static private function filterRows( $rows, $onlyPrioritized )
2045 {
2046 if ( !$onlyPrioritized )
2047 {
2048 return $rows;
2049 }
2050 $idMap = array();
2051 foreach ( $rows as $row )
2052 {
2053 if ( !isset( $idMap[$row['id']] ) )
2054 {
2055 $idMap[$row['id']] = array();
2056 }
2057 $idMap[$row['id']][] = $row;
2058 }
2059
2060 $rows = array();
2061 foreach ( $idMap as $id => $langRows )
2062 {
2063 $rows[] = eZURLAliasML::choosePrioritizedRow( $langRows );
2064 }
2065
2066 return $rows;
2067 }
2068
2076 static private function languageScore( $mask )
2077 {
2078 $prioritizedLanguages = eZContentLanguage::prioritizedLanguages();
2079 $scores = array();
2080 $score = 1;
2081 $mask = (int)$mask;
2082 krsort( $prioritizedLanguages );
2083 foreach ( $prioritizedLanguages as $prioritizedLanguage )
2084 {
2085 $id = (int)$prioritizedLanguage->attribute( 'id' );
2086 if ( $id & $mask )
2087 {
2088 $scores[] = $score;
2089 }
2090 ++$score;
2091 }
2092 if ( count( $scores ) > 0 )
2093 {
2094 return max( $scores );
2095 }
2096 else
2097 {
2098 return 0;
2099 }
2100 }
2101
2111 static public function actionToUrl( $action )
2112 {
2113 if ( !preg_match( "#^([a-zA-Z0-9_]+):(.+)?$#", $action, $matches ) )
2114 {
2115 eZDebug::writeError( "Action is not of valid syntax '{$action}'" );
2116 return false;
2117 }
2118
2119 $type = $matches[1];
2120 $args = '';
2121 if ( isset( $matches[2] ) )
2122 $args = $matches[2];
2123 switch ( $type )
2124 {
2125 case 'eznode':
2126 if ( !is_numeric( $args ) )
2127 {
2128 eZDebug::writeError( "Arguments to eznode action must be an integer, got '{$args}'" );
2129 return false;
2130 }
2131 $url = 'content/view/full/' . $args;
2132 break;
2133
2134 case 'module':
2135 $url = $args;
2136 break;
2137
2138 case 'nop':
2139 $siteINI = eZINI::instance();
2140 $url = $siteINI->variable( 'URLTranslator', 'LoadOnPartialAliasPath' );
2141 break;
2142
2143 default:
2144 eZDebug::writeError( "Unknown action type '{$type}', cannot handle it" );
2145 return false;
2146 }
2147 return $url;
2148 }
2149
2161 static public function urlToAction( $url )
2162 {
2163 if ( preg_match( "#^content/view/full/([0-9]+)$#", $url, $matches ) )
2164 {
2165 return "eznode:" . $matches[1];
2166 }
2167 if ( preg_match( "#^([a-zA-Z0-9]+)/#", $url, $matches ) )
2168 {
2169 $name = $matches[1];
2170 $module = eZModule::exists( $name );
2171 if ( $module !== null )
2172 return 'module:' . $url;
2173 }
2174 return false;
2175 }
2176
2182 static public function cleanURL( $url )
2183 {
2184 return trim( $url, '/ ' );
2185 }
2186
2199 static public function sanitizeURL( $url )
2200 {
2201 $url = preg_replace( "#//+#", "/", trim( $url, '/' ) );
2202 return $url;
2203 }
2204
2210 static private function generateSelect( $table, $i, $len )
2211 {
2212 if ( $i == $len - 1 )
2213 {
2214 $select = "{$table}.id AS {$table}_id, {$table}.link AS {$table}_link, {$table}.text AS {$table}_text, {$table}.text_md5 AS {$table}_text_md5, {$table}.action AS {$table}_action";
2215 }
2216 else
2217 {
2218 $select = "{$table}.id AS {$table}_id, {$table}.link AS {$table}_link, {$table}.text AS {$table}_text, {$table}.text_md5 AS {$table}_text_md5";
2219 }
2220 return $select;
2221 }
2222
2228 static private function generateFullSelect( $table )
2229 {
2230 $select = "{$table}.id AS {$table}_id, {$table}.parent AS {$table}_parent, {$table}.lang_mask AS {$table}_lang_mask, {$table}.text AS {$table}_text, {$table}.text_md5 AS {$table}_text_md5, {$table}.action AS {$table}_action, {$table}.link AS {$table}_link";
2231 return $select;
2232 }
2233
2239 static private function generateCond( $table, $prevTable, $i, $langMask, $element )
2240 {
2241 $db = eZDB::instance();
2242 if ( $i == 0 )
2243 {
2244 $cond = "{$table}.parent = 0 AND ({$langMask}) AND {$table}.text_md5 = " . eZURLAliasML::md5( $db, $element );
2245 }
2246 else
2247 {
2248 $cond = "{$table}.parent = {$prevTable}.link AND ({$langMask}) AND {$table}.text_md5 = " . eZURLAliasML::md5( $db, $element );
2249 }
2250 return $cond;
2251 }
2252
2259 static private function generateGlobCond( $table, $prevTable, $i, $langMask, $glob )
2260 {
2261 $db = eZDB::instance();
2262 if ( $i == 0 )
2263 {
2264 $cond = "{$table}.parent = 0 AND ({$langMask}) AND {$table}.text LIKE '" . $db->escapeString( $glob ) . "%'";
2265 }
2266 else
2267 {
2268 $cond = "{$table}.parent = {$prevTable}.link AND ({$langMask}) AND {$table}.text LIKE '" . $db->escapeString( $glob ) . "%'";
2269 }
2270 return $cond;
2271 }
2272
2292 static public function convertToAlias( $urlElement, $defaultValue = false )
2293 {
2294 $trans = eZCharTransform::instance();
2295
2296 $ini = eZINI::instance();
2297 $group = $ini->variable( 'URLTranslator', 'TransformationGroup' );
2298
2299 $urlElement = $trans->transformByGroup( $urlElement, $group );
2300 if ( strlen( $urlElement ) == 0 )
2301 {
2302 if ( $defaultValue === false )
2303 $urlElement = '_1';
2304 else
2305 {
2306 $urlElement = $defaultValue;
2307 $urlElement = $trans->transformByGroup( $urlElement, $group );
2308 }
2309 }
2310 return $urlElement;
2311 }
2312
2332 static public function convertToAliasCompat( $urlElement, $defaultValue = false )
2333 {
2334 $trans = eZCharTransform::instance();
2335
2336 $urlElement = $trans->transformByGroup( $urlElement, "urlalias_compat" );
2337 if ( strlen( $urlElement ) == 0 )
2338 {
2339 if ( $defaultValue === false )
2340 $urlElement = '_1';
2341 else
2342 {
2343 $urlElement = $defaultValue;
2344 $urlElement = $trans->transformByGroup( $urlElement, "urlalias_compat" );
2345 }
2346 }
2347 return $urlElement;
2348 }
2349
2357 static public function convertPathToAlias( $pathURL )
2358 {
2359 $result = array();
2360
2361 $elements = explode( '/', $pathURL );
2362
2363 foreach ( $elements as $element )
2364 {
2365 $element = eZURLAliasML::convertToAlias( $element );
2366 $result[] = $element;
2367 }
2368
2369 return implode( '/', $result );
2370 }
2371
2377 static public function nodeIDFromAction( $action )
2378 {
2379 $nodeID = false;
2380 $pos = strpos( $action, 'eznode:' );
2381 if ( $pos === 0 ) // make sure $action starts from 'eznode:'
2382 $nodeID = substr( $action, strlen( 'eznode:' ) );
2383
2384 return $nodeID;
2385 }
2386
2395 static private function md5( $db, $text, $escape = true )
2396 {
2397 // Special case for Oracle since it cannot calculate MD5 for empty strings
2398 if ( strlen( $text ) == 0 && $db->databaseName() == 'oracle' )
2399 return "'" . $db->escapeString( md5( $text ) ) . "'";
2400
2401 if ( $escape )
2402 $text = $db->escapeString( eZURLAliasML::strtolower( $text ) );
2403 return $db->md5( "'" . $text . "'" );
2404 }
2405
2406 static function getNewID()
2407 {
2408 $db = eZDB::instance();
2409 if ( $db->supportsDefaultValuesInsertion() )
2410 {
2411 $db->query( 'INSERT INTO ezurlalias_ml_incr DEFAULT VALUES' );
2412 }
2413 else
2414 {
2415 // can not use VALUES(DEFAULT), because of http://bugs.mysql.com/bug.php?id=42270
2416 $db->query( 'INSERT INTO ezurlalias_ml_incr(id) VALUES(NULL)' );
2417 }
2418
2419 return $db->lastSerialID( 'ezurlalias_ml_incr', 'id' );
2420 }
2421 }
2422
2423 ?>
eZCharTransform\instance
static instance()
Definition: ezchartransform.php:434
eZContentLanguage
Definition: ezcontentlanguage.php:12
eZContentLanguage\topPriorityLanguage
static topPriorityLanguage()
Definition: ezcontentlanguage.php:404
eZContentLanguage\clearPrioritizedLanguages
static clearPrioritizedLanguages()
Definition: ezcontentlanguage.php:393
eZContentLanguage\prioritizedLanguages
static prioritizedLanguages( $languageList=false)
Definition: ezcontentlanguage.php:294
eZContentLanguage\maskByLocale
static maskByLocale( $locales, $setZerothBit=false)
Definition: ezcontentlanguage.php:546
eZContentLanguage\languagesSQLFilter
static languagesSQLFilter( $languageListTable, $languageListAttributeName='language_mask')
Definition: ezcontentlanguage.php:659
eZContentLanguage\setPrioritizedLanguages
static setPrioritizedLanguages( $languages)
Definition: ezcontentlanguage.php:381
eZContentLanguage\fetchByLocale
static fetchByLocale( $locale, $createIfNotExist=false)
Definition: ezcontentlanguage.php:264
eZContentObject\fetchByNodeID
static fetchByNodeID( $nodeID, $asObject=true)
Definition: ezcontentobject.php:1072
eZDB\instance
static instance( $databaseImplementation=false, $databaseParameters=false, $forceNewInstance=false)
Definition: ezdb.php:117
eZDebug\writeError
static writeError( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:545
eZDebug\writeWarning
static writeWarning( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:502
eZModule\exists
static exists( $moduleName, $pathList=null, $showError=false)
Definition: ezmodule.php:1990
eZPersistentObject
Definition: ezpersistentobject.php:33
eZPersistentObject\handleRows
static handleRows( $rows, $class_name, $asObject)
Definition: ezpersistentobject.php:963
eZPersistentObject\count
static count( $def, $conds=null, $field=null)
Definition: ezpersistentobject.php:187
eZPersistentObject\attribute
attribute( $attr, $noFunction=false)
Definition: ezpersistentobject.php:1329
eZTextCodec\internalCharset
static internalCharset()
Definition: eztextcodec.php:546
eZURI
Definition: ezuri.php:28
eZURI\isEmpty
isEmpty()
Definition: ezuri.php:316
eZURI\element
element( $index=0, $relative=true)
Definition: ezuri.php:328
eZURLAliasML
Handles URL aliases in eZ Publish.
Definition: ezurlaliasml.php:58
eZURLAliasML\$TextMD5
$TextMD5
Definition: ezurlaliasml.php:96
eZURLAliasML\store
store( $fieldFilters=null)
Definition: ezurlaliasml.php:270
eZURLAliasML\nodeIDFromAction
static nodeIDFromAction( $action)
Definition: ezurlaliasml.php:2377
eZURLAliasML\$ID
$ID
Definition: ezurlaliasml.php:76
eZURLAliasML\fetchByAction
static fetchByAction( $actionName, $actionValue, $maskLanguages=false, $onlyPrioritized=false, $includeRedirections=false)
Definition: ezurlaliasml.php:967
eZURLAliasML\fetchNodeIDByPath
static fetchNodeIDByPath( $uriString, $glob=false)
Definition: ezurlaliasml.php:1396
eZURLAliasML\definition
static definition()
Definition: ezurlaliasml.php:143
eZURLAliasML\dbError
static dbError( $db)
Definition: ezurlaliasml.php:911
eZURLAliasML\generateCond
static generateCond( $table, $prevTable, $i, $langMask, $element)
Definition: ezurlaliasml.php:2239
eZURLAliasML\$Link
$Link
Definition: ezurlaliasml.php:86
eZURLAliasML\getPath
getPath( $locale=null, $incomingLanguageList=null)
Definition: ezurlaliasml.php:383
eZURLAliasML\urlTranslationEnabledByUri
static urlTranslationEnabledByUri(eZURI $uri)
Definition: ezurlaliasml.php:1857
eZURLAliasML\__construct
__construct( $row)
Definition: ezurlaliasml.php:133
eZURLAliasML\$IsAlias
$IsAlias
Definition: ezurlaliasml.php:121
eZURLAliasML\getNewID
static getNewID()
Definition: ezurlaliasml.php:2406
eZURLAliasML\choosePrioritizedRow
static choosePrioritizedRow( $rows)
Definition: ezurlaliasml.php:2003
eZURLAliasML\generateGlobCond
static generateGlobCond( $table, $prevTable, $i, $langMask, $glob)
Definition: ezurlaliasml.php:2259
eZURLAliasML\$Text
$Text
Definition: ezurlaliasml.php:91
eZURLAliasML\sanitizeURL
static sanitizeURL( $url)
Definition: ezurlaliasml.php:2199
eZURLAliasML\removeByAction
static removeByAction( $actionName, $actionValue)
Definition: ezurlaliasml.php:304
eZURLAliasML\$Parent
$Parent
Definition: ezurlaliasml.php:81
eZURLAliasML\actionToUrl
static actionToUrl( $action)
Definition: ezurlaliasml.php:2111
eZURLAliasML\removePathPrefixFromURI
static removePathPrefixFromURI($uriString)
Definition: ezurlaliasml.php:1824
eZURLAliasML\convertToAlias
static convertToAlias( $urlElement, $defaultValue=false)
Definition: ezurlaliasml.php:2292
eZURLAliasML\removeSingleEntry
static removeSingleEntry( $parentID, $textMD5, $language)
Definition: ezurlaliasml.php:323
eZURLAliasML\fetchByParentID
static fetchByParentID( $id, $maskLanguages=false, $onlyPrioritized=false, $includeRedirections=true)
Definition: ezurlaliasml.php:1049
eZURLAliasML\convertPathToAlias
static convertPathToAlias( $pathURL)
Definition: ezurlaliasml.php:2357
eZURLAliasML\fetchPathByActionList
static fetchPathByActionList( $actionName, $actionValues, $locale=null)
Definition: ezurlaliasml.php:1103
eZURLAliasML\cleanURL
static cleanURL( $url)
Definition: ezurlaliasml.php:2182
eZURLAliasML\getChildren
getChildren()
Definition: ezurlaliasml.php:369
eZURLAliasML\storePath
static storePath( $path, $action, $languageName=false, $linkID=false, $alwaysAvailable=false, $rootID=false, $cleanupElements=true, $autoAdjustName=false, $reportErrors=true, $aliasRedirects=true)
Definition: ezurlaliasml.php:454
eZURLAliasML\create
static create( $element, $action, $parentID, $language)
Definition: ezurlaliasml.php:239
eZURLAliasML\filterRows
static filterRows( $rows, $onlyPrioritized)
Definition: ezurlaliasml.php:2044
eZURLAliasML\LINK_ALREADY_TAKEN
const LINK_ALREADY_TAKEN
Definition: ezurlaliasml.php:62
eZURLAliasML\actionURL
actionURL()
Definition: ezurlaliasml.php:225
eZURLAliasML\translate
static translate(&$uri, $reverse=false)
Definition: ezurlaliasml.php:1491
eZURLAliasML\reverseTranslate
static reverseTranslate(&$uri, $uriString, $internalURIString)
Definition: ezurlaliasml.php:1740
eZURLAliasML\strtolower
static strtolower( $text)
Definition: ezurlaliasml.php:200
eZURLAliasML\$ActionType
$ActionType
Definition: ezurlaliasml.php:111
eZURLAliasML\findUniqueText
static findUniqueText( $parentElementID, $text, $action, $linkCheck=false, $languageID=false)
Definition: ezurlaliasml.php:1888
eZURLAliasML\LINK_ID_WRONG_ACTION
const LINK_ID_WRONG_ACTION
Definition: ezurlaliasml.php:61
eZURLAliasML\generateSelect
static generateSelect( $table, $i, $len)
Definition: ezurlaliasml.php:2210
eZURLAliasML\setAttribute
setAttribute( $name, $value)
Definition: ezurlaliasml.php:252
eZURLAliasML\languageScore
static languageScore( $mask)
Definition: ezurlaliasml.php:2076
eZURLAliasML\urlToAction
static urlToAction( $url)
Definition: ezurlaliasml.php:2161
eZURLAliasML\$LangMask
$LangMask
Definition: ezurlaliasml.php:101
eZURLAliasML\DB_ERROR
const DB_ERROR
Definition: ezurlaliasml.php:64
eZURLAliasML\setLangMaskAlwaysAvailable
static setLangMaskAlwaysAvailable( $langID, $actionName, $actionValue)
Definition: ezurlaliasml.php:1951
eZURLAliasML\convertToAliasCompat
static convertToAliasCompat( $urlElement, $defaultValue=false)
Definition: ezurlaliasml.php:2332
eZURLAliasML\$Path
$Path
Definition: ezurlaliasml.php:71
eZURLAliasML\generateFullSelect
static generateFullSelect( $table)
Definition: ezurlaliasml.php:2228
eZURLAliasML\md5
static md5( $db, $text, $escape=true)
Definition: ezurlaliasml.php:2395
eZURLAliasML\ACTION_INVALID
const ACTION_INVALID
Definition: ezurlaliasml.php:63
eZURLAliasML\$charset
static $charset
Definition: ezurlaliasml.php:131
eZURLAliasML\$Action
$Action
Definition: ezurlaliasml.php:106
eZURLAliasML\$IsOriginal
$IsOriginal
Definition: ezurlaliasml.php:126
eZURLAliasML\fetchByPath
static fetchByPath( $uriString, $glob=false)
Definition: ezurlaliasml.php:1253
eZURLAliasML\LINK_ID_NOT_FOUND
const LINK_ID_NOT_FOUND
Definition: ezurlaliasml.php:60
eZURLAliasML\getPathPrefix
static getPathPrefix()
Definition: ezurlaliasml.php:1809
eZURLAliasML\$AliasRedirects
$AliasRedirects
Definition: ezurlaliasml.php:116
eZURLWildcard\wildcardExists
static wildcardExists( $uriString)
Definition: ezurlwildcard.php:653
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.