1 <?php 2 /** 3 * Copyright 2014-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file LICENSE for license information (LGPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 7 * 8 * @category Horde 9 * @copyright 2014-2017 Horde LLC 10 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 11 * @package Mime 12 */ 13 14 /** 15 * Provides methods to manipulate/query MIME IDs. 16 * 17 * @author Michael Slusarz <slusarz@horde.org> 18 * @category Horde 19 * @copyright 2014-2017 Horde LLC 20 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 21 * @package Mime 22 * @since 2.5.0 23 */ 24 class Horde_Mime_Id 25 { 26 /* Constants for idArithmetic() method. */ 27 const ID_DOWN = 1; 28 const ID_NEXT = 2; 29 const ID_PREV = 3; 30 const ID_UP = 4; 31 32 /** 33 * MIME ID. 34 * 35 * @var string 36 */ 37 public $id; 38 39 /** 40 * Constructor. 41 * 42 * @param string $id MIME ID. 43 */ 44 public function __construct($id) 45 { 46 $this->id = $id; 47 } 48 49 /** 50 */ 51 public function __toString() 52 { 53 return $this->id; 54 } 55 56 /** 57 * Performs MIME ID "arithmetic". 58 * 59 * @param string $action One of: 60 * - ID_DOWN: ID of child. Note: ID_DOWN will first traverse to "$id.0" 61 * if given an ID *NOT* of the form "$id.0". If given an ID of 62 * the form "$id.0", ID_DOWN will traverse to "$id.1". This 63 * behavior can be avoided if 'no_rfc822' option is set. 64 * - ID_NEXT: ID of next sibling. 65 * - ID_PREV: ID of previous sibling. 66 * - ID_UP: ID of parent. Note: ID_UP will first traverse to "$id.0" if 67 * given an ID *NOT* of the form "$id.0". If given an ID of the 68 * form "$id.0", ID_UP will traverse to "$id". This behavior can 69 * be avoided if 'no_rfc822' option is set. 70 * @param array $options Additional options: 71 * - count: (integer) How many levels to traverse. 72 * DEFAULT: 1 73 * - no_rfc822: (boolean) Don't traverse RFC 822 sub-levels. 74 * DEFAULT: false 75 * 76 * @return mixed The resulting ID string, or null if that ID can not 77 * exist. 78 */ 79 public function idArithmetic($action, array $options = array()) 80 { 81 return $this->_idArithmetic($this->id, $action, array_merge(array( 82 'count' => 1 83 ), $options)); 84 } 85 86 /** 87 * @see idArithmetic() 88 */ 89 protected function _idArithmetic($id, $action, $options) 90 { 91 $pos = strrpos($id, '.'); 92 $end = ($pos === false) ? $id : substr($id, $pos + 1); 93 94 switch ($action) { 95 case self::ID_DOWN: 96 if ($end == '0') { 97 $id = ($pos === false) ? 1 : substr_replace($id, '1', $pos + 1); 98 } else { 99 $id .= empty($options['no_rfc822']) ? '.0' : '.1'; 100 } 101 break; 102 103 case self::ID_NEXT: 104 ++$end; 105 $id = ($pos === false) ? $end : substr_replace($id, $end, $pos + 1); 106 break; 107 108 case self::ID_PREV: 109 if (($end == '0') || 110 (empty($options['no_rfc822']) && ($end == '1'))) { 111 $id = null; 112 } elseif ($pos === false) { 113 $id = --$end; 114 } else { 115 $id = substr_replace($id, --$end, $pos + 1); 116 } 117 break; 118 119 case self::ID_UP: 120 if ($pos === false) { 121 $id = ($end == '0') ? null : '0'; 122 } elseif (!empty($options['no_rfc822']) || ($end == '0')) { 123 $id = substr($id, 0, $pos); 124 } else { 125 $id = substr_replace($id, '0', $pos + 1); 126 } 127 break; 128 } 129 130 return (!is_null($id) && --$options['count']) 131 ? $this->_idArithmetic($id, $action, $options) 132 : $id; 133 } 134 135 /** 136 * Determines if a given MIME ID lives underneath a base ID. 137 * 138 * @param string $id The MIME ID to query. 139 * 140 * @return boolean Whether $id lives under the base ID ($this->id). 141 */ 142 public function isChild($id) 143 { 144 $base = (substr($this->id, -2) == '.0') 145 ? substr($this->id, 0, -1) 146 : rtrim($this->id, '.') . '.'; 147 148 return ((($base == 0) && ($id != 0)) || 149 (strpos(strval($id), strval($base)) === 0)); 150 } 151 152 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body