00001 <?php
00007 define( 'SMW_URI_MODE_EMAIL', 1 );
00008 define( 'SMW_URI_MODE_URI', 3 );
00009 define( 'SMW_URI_MODE_ANNOURI', 4 );
00010 define( 'SMW_URI_MODE_TEL', 5 );
00011
00021 class SMWURIValue extends SMWDataValue {
00022
00027 protected $m_wikitext;
00033 private $m_mode;
00034
00035 public function __construct( $typeid ) {
00036 parent::__construct( $typeid );
00037 switch ( $typeid ) {
00038 case '_ema':
00039 $this->m_mode = SMW_URI_MODE_EMAIL;
00040 break;
00041 case '_anu':
00042 $this->m_mode = SMW_URI_MODE_ANNOURI;
00043 break;
00044 case '_tel':
00045 $this->m_mode = SMW_URI_MODE_TEL;
00046 break;
00047 case '_uri': case '_url': case '__spu': default:
00048 $this->m_mode = SMW_URI_MODE_URI;
00049 break;
00050 }
00051 }
00052
00053 protected function parseUserValue( $value ) {
00054 $value = trim( $value );
00055 $this->m_wikitext = $value;
00056 if ( $this->m_caption === false ) {
00057 $this->m_caption = $this->m_wikitext;
00058 }
00059
00060 $scheme = $hierpart = $query = $fragment = '';
00061 if ( $value === '' ) {
00062 $this->addError( wfMsgForContent( 'smw_emptystring' ) );
00063 $this->m_dataitem = new SMWDIUri( 'http', '//example.com', '', '', $this->m_typeid );
00064 return;
00065 }
00066
00067 switch ( $this->m_mode ) {
00068 case SMW_URI_MODE_URI: case SMW_URI_MODE_ANNOURI:
00069 $parts = explode( ':', $value, 2 );
00070 if ( count( $parts ) == 1 ) {
00071 $value = 'http://' . $value;
00072 $parts[1] = $parts[0];
00073 $parts[0] = 'http';
00074 }
00075
00076 $uri_blacklist = explode( "\n", wfMsgForContent( 'smw_uri_blacklist' ) );
00077 foreach ( $uri_blacklist as $uri ) {
00078 $uri = trim( $uri );
00079 if ( $uri == mb_substr( $value, 0, mb_strlen( $uri ) ) ) {
00080 $this->addError( wfMsgForContent( 'smw_baduri', $value ) );
00081 $this->m_dataitem = new SMWDIUri( 'http', '//example.com', '', '', $this->m_typeid );
00082 return;
00083 }
00084 }
00085
00086 $scheme = $parts[0];
00087 $parts = explode( '?', $parts[1], 2 );
00088 if ( count( $parts ) == 2 ) {
00089 $hierpart = $parts[0];
00090 $parts = explode( '#', $parts[1], 2 );
00091 $query = $parts[0];
00092 $fragment = ( count( $parts ) == 2 ) ? $parts[1] : '';
00093 } else {
00094 $query = '';
00095 $parts = explode( '#', $parts[0], 2 );
00096 $hierpart = $parts[0];
00097 $fragment = ( count( $parts ) == 2 ) ? $parts[1] : '';
00098 }
00099
00100
00101 $hierpart = str_replace( array( '%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25' ), array( ':', '/', '#', '@', '?', '=', '&', '%' ), rawurlencode( $hierpart ) );
00102 $query = str_replace( array( '%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25' ), array( ':', '/', '#', '@', '?', '=', '&', '%' ), rawurlencode( $query ) );
00103 $fragment = str_replace( array( '%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25' ), array( ':', '/', '#', '@', '?', '=', '&', '%' ), rawurlencode( $fragment ) );
00107
00108 if ( substr( $hierpart, 0, 2 ) === '//' ) {
00109 $hierpart = substr( $hierpart, 2 );
00110 }
00111 break;
00112 case SMW_URI_MODE_TEL:
00113 $scheme = 'tel';
00114 if ( substr( $value, 0, 4 ) === 'tel:' ) {
00115 $value = substr( $value, 4 );
00116 $this->m_wikitext = $value;
00117 }
00118 $hierpart = preg_replace( '/(?<=[0-9]) (?=[0-9])/', '\1-\2', $value );
00119 $hierpart = str_replace( ' ', '', $hierpart );
00120 if ( substr( $hierpart, 0, 2 ) == '00' ) {
00121 $hierpart = '+' . substr( $hierpart, 2 );
00122 }
00123 if ( ( strlen( preg_replace( '/[^0-9]/', '', $hierpart ) ) < 6 ) ||
00124 ( preg_match( '<[-+./][-./]>', $hierpart ) ) ||
00125 ( !SMWURIValue::isValidTelURI( 'tel:' . $hierpart ) ) ) {
00126 $this->addError( wfMsgForContent( 'smw_baduri', $this->m_wikitext ) );
00127 }
00128 break;
00129 case SMW_URI_MODE_EMAIL:
00130 $scheme = 'mailto';
00131 if ( strpos( $value, 'mailto:' ) === 0 ) {
00132 $value = substr( $value, 7 );
00133 $this->m_wikitext = $value;
00134 }
00135
00136 $check = method_exists( 'Sanitizer', 'validateEmail' ) ? Sanitizer::validateEmail( $value ) : self::validateEmail( $value );
00137 if ( !$check ) {
00139 $this->addError( wfMsgForContent( 'smw_baduri', $value ) );
00140 break;
00141 }
00142 $hierpart = str_replace( array( '%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25' ), array( ':', '/', '#', '@', '?', '=', '&', '%' ), rawurlencode( $value ) );
00143 }
00144
00145
00146 try {
00147 $this->m_dataitem = new SMWDIUri( $scheme, $hierpart, $query, $fragment, $this->m_typeid );
00148 } catch ( SMWDataItemException $e ) {
00149 $this->addError( wfMsgForContent( 'smw_baduri', $this->m_wikitext ) );
00150 $this->m_dataitem = new SMWDIUri( 'http', '//example.com', '', '', $this->m_typeid );
00151 }
00152 }
00153
00159 protected static function isValidTelURI( $s ) {
00160 $tel_uri_regex = '<^tel:\+[0-9./-]*[0-9][0-9./-]*(;[0-9a-zA-Z-]+=(%[0-9a-zA-Z][0-9a-zA-Z]|[0-9a-zA-Z._~:/?#[\]@!$&\'()*+,;=-])*)*$>';
00161 return (bool) preg_match( $tel_uri_regex, $s );
00162 }
00163
00169 protected function loadDataItem( SMWDataItem $dataItem ) {
00170 if ( $dataItem->getDIType() == SMWDataItem::TYPE_URI ) {
00171 $this->m_dataitem = $dataItem;
00172 if ( $this->m_mode == SMW_URI_MODE_EMAIL ) {
00173 $this->m_wikitext = substr( $dataItem->getURI(), 7 );
00174 } elseif ( $this->m_mode == SMW_URI_MODE_TEL ) {
00175 $this->m_wikitext = substr( $dataItem->getURI(), 4 );
00176 } else {
00177 $this->m_wikitext = $dataItem->getURI();
00178 }
00179 $this->m_caption = $this->m_wikitext;
00180 return true;
00181 } else {
00182 return false;
00183 }
00184 }
00185
00186 public function getShortWikiText( $linked = null ) {
00187 $url = $this->getURL();
00188 if ( is_null( $linked ) || ( $linked === false ) || ( $this->m_outformat == '-' ) || ( $url === '' ) || ( $this->m_caption === '' ) ) {
00189 return $this->m_caption;
00190 } else {
00191 return '[' . $url . ' ' . $this->m_caption . ']';
00192 }
00193 }
00194
00195 public function getShortHTMLText( $linker = null ) {
00196 $url = $this->getURL();
00197 if ( is_null( $linker ) || ( !$this->isValid() ) || ( $this->m_outformat == '-' ) || ( $url === '' ) || ( $this->m_caption === '' ) ) {
00198 return $this->m_caption;
00199 } else {
00200 return $linker->makeExternalLink( $url, $this->m_caption );
00201 }
00202 }
00203
00204 public function getLongWikiText( $linked = null ) {
00205 if ( !$this->isValid() ) {
00206 return $this->getErrorText();
00207 }
00208 $url = $this->getURL();
00209
00210 if ( is_null( $linked ) || ( $linked === false ) || ( $this->m_outformat == '-' ) || ( $url === '' ) ) {
00211 return $this->m_wikitext;
00212 } else {
00213 return '[' . $url . ' ' . $this->m_wikitext . ']';
00214 }
00215 }
00216
00217 public function getLongHTMLText( $linker = null ) {
00218 if ( !$this->isValid() ) {
00219 return $this->getErrorText();
00220 }
00221
00222 $url = $this->getURL();
00223
00224 if ( is_null( $linker ) || ( $this->m_outformat == '-' ) || ( $url === '' ) ) {
00225 return htmlspecialchars( $this->m_wikitext );
00226 } else {
00227 return $linker->makeExternalLink( $url, $this->m_wikitext );
00228 }
00229 }
00230
00231 public function getWikiValue() {
00232 return $this->m_wikitext;
00233 }
00234
00235 public function getURI() {
00236 return $this->m_dataitem->getURI();
00237 }
00238
00239 protected function getServiceLinkParams() {
00240
00241
00242
00243 return array( rawurlencode( $this->m_dataitem->getURI() ) );
00244 }
00245
00251 public function getURL() {
00252 global $wgUrlProtocols;
00253
00254 foreach ( $wgUrlProtocols as $prot ) {
00255 if ( ( $prot == $this->m_dataitem->getScheme() . ':' ) || ( $prot == $this->m_dataitem->getScheme() . '://' ) ) {
00256 return $this->m_dataitem->getURI();
00257 }
00258 }
00259
00260 return '';
00261 }
00262
00268 public static function validateEmail( $addr ) {
00269 $result = null;
00270 if ( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) {
00271 return $result;
00272 }
00273
00274
00275
00276
00277 $rfc5322_atext = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~" ;
00278 $rfc1034_ldh_str = "a-z0-9\\-" ;
00279
00280 $HTML5_email_regexp = "/
00281 ^ # start of string
00282 [$rfc5322_atext\\.]+ # user part which is liberal :p
00283 @ # 'apostrophe'
00284 [$rfc1034_ldh_str]+ # First domain part
00285 (\\.[$rfc1034_ldh_str]+)* # Following part prefixed with a dot
00286 $ # End of string
00287 /ix" ;
00288
00289 return (bool) preg_match( $HTML5_email_regexp, $addr );
00290 }
00291
00292 }
00293