/lib/eztemplate/classes/eztemplatestringoperator.php

https://github.com/GunioRobot/ezpublish · PHP · 734 lines · 678 code · 25 blank · 31 comment · 14 complexity · 166c0836ef9c896fc434ced8c7a18dd5 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the eZTemplateStringOperator class.
  4. *
  5. * @copyright Copyright (C) 1999-2011 eZ Systems AS. All rights reserved.
  6. * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
  7. * @version //autogentag//
  8. * @package lib
  9. */
  10. /*!
  11. \class eZTemplateStringOperator eztemplatestringoperator.php
  12. \ingroup eZTemplateOperators
  13. \code
  14. \endcode
  15. */
  16. class eZTemplateStringOperator
  17. {
  18. /*!
  19. Constructor.
  20. */
  21. function eZTemplateStringOperator()
  22. {
  23. $this->Operators = array( 'upcase', 'downcase',
  24. 'count_words', 'count_chars',
  25. 'trim', 'break', 'wrap', 'shorten', 'pad',
  26. 'upfirst', 'upword',
  27. 'simplify', 'wash',
  28. 'chr', 'ord');
  29. foreach ( $this->Operators as $operator )
  30. {
  31. $name = $operator . 'Name';
  32. $name[0] = $name[0] & "\xdf";
  33. $this->$name = $operator;
  34. }
  35. $this->phpMap = array ('upcase' => 'mb_strtoupper,strtoupper',
  36. 'downcase' => 'mb_strtolower,strtolower',
  37. 'break' => 'nl2br',
  38. 'count_chars' => 'mb_strlen,strlen');
  39. $this->customMap = array ( 'count_words' => array( 'return' => 'int',
  40. 'code' => '$result = preg_match_all( "#(\w+)#", $staticValues[0], $dummy );'
  41. ),
  42. 'chr' => array( 'return' => 'string',
  43. 'code' => '$codec = eZTextCodec::instance( "unicode", false );' . "\n" .
  44. '$result = $codec->convertString( $staticValues[0] );'
  45. ),
  46. 'ord' => array( 'return' => 'string',
  47. 'code' => '$codec = eZTextCodec::instance( false, "unicode" );' . "\n" .
  48. '$result = $codec->convertString( $staticValues[0] );'
  49. ),
  50. 'pad' => array( 'return' => 'string',
  51. 'code' => '$result = $paramCount == 2 ? str_pad( $staticValues[0], $staticValues[1] ) : str_pad ( $staticValues[0], $staticValues[1], $staticValues[2] );',
  52. 'code2' => '$result = str_pad( $staticValues[0], $staticValues[1] );',
  53. 'code3' => '$result = str_pad( $staticValues[0], $staticValues[1], $staticValues[2] );',
  54. ),
  55. 'trim' => array( 'return' => 'string',
  56. 'code' => '$result = $paramCount == 1 ? trim( $staticValues[0] ) : trim ( $staticValues[0], $staticValues[1] );',
  57. 'code1' => '$result = trim( $staticValues[0] );',
  58. 'code2' => '$result = trim( $staticValues[0], $staticValues[1] );',
  59. ),
  60. 'wrap' => array( 'return' => 'string',
  61. 'code1' => '$result = wordwrap( $staticValues[0] );',
  62. 'code2' => '$result = wordwrap( $staticValues[0], $staticValues[1] );',
  63. 'code3' => '$result = wordwrap( $staticValues[0], $staticValues[1], $staticValues[2] );',
  64. 'code4' => '$result = wordwrap( $staticValues[0], $staticValues[1], $staticValues[2], $staticValues[3] );',
  65. ),
  66. 'simplify' => array( 'return' => 'string',
  67. 'code' => 'if ( $paramCount == 1 )
  68. {
  69. $replacer = " ";
  70. }
  71. else
  72. {
  73. $replacer = $staticValues[1];
  74. }
  75. $result = preg_replace( "/".$replacer."{2,}/", $replacer, $staticValues[0] );',
  76. 'code1' => '$result = preg_replace( "/ {2,}/", " ", $staticValues[0] );',
  77. 'code2' => '$result = preg_replace( "/".$staticValues[1]."{2,}/", $staticValues[1], $staticValues[0] );',
  78. ),
  79. 'shorten' => array( 'return' => 'string',
  80. 'code' => '$length = 80; $seq = "..."; $trimType = "right";
  81. if ( $paramCount > 1 )
  82. {
  83. $length = $staticValues[1];
  84. }
  85. if ( $paramCount > 2 )
  86. {
  87. $seq = $staticValues[2];
  88. }
  89. if ( $paramCount > 3 )
  90. {
  91. $trimType = $staticValues[3];
  92. }
  93. if ( $trimType === "middle" )
  94. {
  95. $appendedStrLen = $strlenFunc( $seq );
  96. if ( $length > $appendedStrLen && ( $strlenFunc( $staticValues[0] ) > $length ) )
  97. {
  98. $operatorValueLength = $strlenFunc( $staticValues[0] );
  99. $chop = $length - $appendedStrLen;
  100. $middlePos = (int)($chop / 2);
  101. $leftPartLength = $middlePos;
  102. $rightPartLength = $chop - $middlePos;
  103. $result = trim( $substrFunc( $staticValues[0], 0, $leftPartLength ) . $seq . $substrFunc( $staticValues[0], $operatorValueLength - $rightPartLength, $rightPartLength ) );
  104. }
  105. else
  106. {
  107. $result = $staticValues[0];
  108. }
  109. }
  110. else // default: trim_type === "right"
  111. {
  112. $maxLength = $length - $strlenFunc( $seq );
  113. if ( ( $strlenFunc( $staticValues[0] ) > $length ) && $strlenFunc( $staticValues[0] ) > $maxLength )
  114. {
  115. $result = trim( $substrFunc( $staticValues[0], 0, $maxLength) ) . $seq;
  116. }
  117. else
  118. {
  119. $result = $staticValues[0];
  120. }
  121. }'
  122. ),
  123. 'upfirst' => array( 'return' => 'string',
  124. 'code' => '$i18nIni = eZINI::instance( \'i18n.ini\' );
  125. $hasMBString = ( $i18nIni->variable( \'CharacterSettings\', \'MBStringExtension\' ) == \'enabled\' and
  126. function_exists( "mb_strtoupper" ) and
  127. function_exists( "mb_substr" ) and
  128. function_exists( "mb_strlen" ) );
  129. if ( $hasMBString )
  130. {
  131. $encoding = eZTextCodec::internalCharset();
  132. $firstLetter = mb_strtoupper( mb_substr( $staticValues[0], 0, 1, $encoding ), $encoding );
  133. $remainingText = mb_substr( $staticValues[0], 1, mb_strlen( $staticValues[0], $encoding ), $encoding );
  134. $result = $firstLetter . $remainingText;
  135. }
  136. else
  137. {
  138. $result = ucfirst( $staticValues[0] );
  139. }'
  140. ),
  141. 'upword' => array( 'return' => 'string',
  142. 'code' => ' $i18nIni = eZINI::instance( \'i18n.ini\' );
  143. $hasMBString = ( $i18nIni->variable( \'CharacterSettings\', \'MBStringExtension\' ) == \'enabled\' and
  144. function_exists( "mb_strtoupper" ) and
  145. function_exists( "mb_substr" ) and
  146. function_exists( "mb_strlen" ) );
  147. if ( $hasMBString )
  148. {
  149. $encoding = eZTextCodec::internalCharset();
  150. $words = explode( " ", $staticValues[0] );
  151. $newString = array();
  152. foreach ( $words as $word )
  153. {
  154. $firstLetter = mb_strtoupper( mb_substr( $word, 0, 1, $encoding ), $encoding );
  155. $remainingText = mb_substr( $word, 1, mb_strlen( $word, $encoding ), $encoding );
  156. $newString[] = $firstLetter . $remainingText;
  157. }
  158. $result = implode( " ", $newString );
  159. unset( $newString, $words );
  160. }
  161. else
  162. {
  163. $result = ucwords( $staticValues[0] );
  164. }'
  165. )
  166. );
  167. }
  168. /*!
  169. Returns the template operators.
  170. */
  171. function operatorList()
  172. {
  173. return $this->Operators;
  174. }
  175. function operatorTemplateHints()
  176. {
  177. $hints = array(
  178. $this->BreakName => array( 'parameters' => false, 'element-transformation-func' => 'phpMapTransformation' ),
  179. $this->Count_charsName => array( 'parameters' => false, 'element-transformation-func' => 'phpMapTransformation' ),
  180. $this->DowncaseName => array( 'parameters' => false, 'element-transformation-func' => 'phpMapTransformation' ),
  181. $this->UpcaseName => array( 'parameters' => false, 'element-transformation-func' => 'phpMapTransformation' ),
  182. $this->UpfirstName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  183. $this->UpwordName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  184. $this->Count_wordsName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  185. $this->ChrName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  186. $this->OrdName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  187. $this->PadName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  188. $this->ShortenName => array( 'parameters' => 3 , 'element-transformation-func' => 'customMapTransformation' ),
  189. $this->SimplifyName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  190. $this->TrimName => array( 'parameters' => 1 , 'element-transformation-func' => 'customMapTransformation' ),
  191. $this->WrapName => array( 'parameters' => false, 'element-transformation-func' => 'customMapTransformation' ),
  192. $this->WashName => array( 'parameters' => 1, 'element-transformation-func' => 'washTransformation' ),
  193. );
  194. foreach ( $this->Operators as $operator )
  195. {
  196. $hints[$operator]['input'] = true;
  197. $hints[$operator]['output'] = true;
  198. $hints[$operator]['element-transformation'] = true;
  199. $hints[$operator]['transform-parameters'] = true;
  200. if ( !isset( $hints[$operator]['input-as-parameter'] ) )
  201. $hints[$operator]['input-as-parameter'] = 'always';
  202. }
  203. return $hints;
  204. }
  205. /*!
  206. \return true to tell the template engine that the parameter list exists per operator type.
  207. */
  208. function namedParameterPerOperator()
  209. {
  210. return true;
  211. }
  212. /*!
  213. See eZTemplateOperator::namedParameterList()
  214. */
  215. function namedParameterList()
  216. {
  217. return array( $this->TrimName => array( 'chars_to_remove' => array( "type" => "string",
  218. "required" => false,
  219. "default" => false ) ),
  220. $this->WrapName => array( 'wrap_at_position' => array( "type" => "integer",
  221. "required" => false,
  222. "default" => false ),
  223. 'break_sequence' => array( "type" => "string",
  224. "required" => false,
  225. "default" => false ),
  226. 'cut' => array( "type" => "boolean",
  227. "required" => false,
  228. "default" => false ) ),
  229. $this->WashName => array( 'type' => array( "type" => "string",
  230. "required" => false,
  231. "default" => "xhtml" ) ),
  232. $this->ShortenName => array( 'chars_to_keep' => array( "type" => "integer",
  233. "required" => false,
  234. "default" => 80 ),
  235. 'str_to_append' => array( "type" => "string",
  236. "required" => false,
  237. "default" => "..." ),
  238. 'trim_type' => array( "type" => "string",
  239. "required" => false,
  240. "default" => "right" ) ),
  241. $this->PadName => array( 'desired_length' => array( "type" => "integer",
  242. "required" => false,
  243. "default" => 80 ),
  244. 'pad_sequence' => array( "type" => "string",
  245. "required" => false,
  246. "default" => " " ) ),
  247. $this->SimplifyName => array ( 'char' => array( "type" => "string",
  248. "required" => false,
  249. "default" => false ) ) );
  250. }
  251. function phpMapTransformation( $operatorName, $node, $tpl, $resourceData,
  252. $element, $lastElement, $elementList, $elementTree, &$parameters )
  253. {
  254. $values = array();
  255. $phpFunctionList = explode( ',', $this->phpMap[$operatorName] );
  256. foreach ( $phpFunctionList as $element )
  257. {
  258. if ( function_exists( $element ) )
  259. {
  260. $phpFunction = $element;
  261. break;
  262. }
  263. }
  264. $newElements = array();
  265. if ( count ( $parameters ) != 1 )
  266. {
  267. return false;
  268. }
  269. if ( eZTemplateNodeTool::isConstantElement( $parameters[0] ) )
  270. {
  271. $text = eZTemplateNodeTool::elementConstantValue( $parameters[0] );
  272. $text = $phpFunction( $text );
  273. $text = str_replace( array( "'" ), array( "\\'" ), $text );
  274. $code = "%output% = '" . $text . "' ;\n";
  275. }
  276. else
  277. {
  278. $values[] = $parameters[0];
  279. $code = "%output% = $phpFunction( %1% );\n";
  280. }
  281. $newElements[] = eZTemplateNodeTool::createCodePieceElement( $code, $values );
  282. return $newElements;
  283. }
  284. function customMapTransformation( $operatorName, $node, $tpl, $resourceData,
  285. $element, $lastElement, $elementList, $elementTree, &$parameters )
  286. {
  287. $values = array();
  288. $newElements = array();
  289. $mapEntry = $this->customMap[$operatorName];
  290. $paramCount = count( $parameters );
  291. $strlenFunc = 'strlen';
  292. $substrFunc = 'substr';
  293. $code = "\$strlenFunc = 'strlen'; \$substrFunc = 'substr';\n";
  294. if ( function_exists( 'mb_strlen' ) )
  295. {
  296. $strlenFunc = 'mb_strlen';
  297. $substrFunc = 'mb_substr';
  298. $code = "\$strlenFunc = 'mb_strlen'; \$substrFunc = 'mb_substr';\n";
  299. }
  300. if ( $paramCount < 1 )
  301. {
  302. return false;
  303. }
  304. $allStatic = true;
  305. $staticValues = array();
  306. $replaceMap = array('$result');
  307. $replacementMap = array('%output%');
  308. for ($i = 0; $i < $paramCount; $i++)
  309. {
  310. if ( eZTemplateNodeTool::isConstantElement( $parameters[$i] ) )
  311. {
  312. $staticValues[$i] = eZTemplateNodeTool::elementConstantValue( $parameters[$i] );
  313. }
  314. else
  315. {
  316. $allStatic = false;
  317. }
  318. }
  319. if ( $allStatic )
  320. {
  321. $result = false;
  322. if ( isset( $mapEntry['code'. $paramCount] ) )
  323. {
  324. eval( $mapEntry['code' . $paramCount] );
  325. }
  326. else
  327. {
  328. eval( $mapEntry['code'] );
  329. }
  330. return array( eZTemplateNodeTool::createConstantElement( $result ) );
  331. }
  332. else
  333. {
  334. $replaceMap = array( '$result', '$paramCount' );
  335. $replacementMap = array( '%output%', $paramCount );
  336. for ( $i = 0; $i < $paramCount; $i++ )
  337. {
  338. $values[] = $parameters[$i];
  339. $replaceMap[] = "\$staticValues[$i]";
  340. $replacementMap[] = '%' . ( $i + 1 ) . '%';
  341. }
  342. if ( isset( $mapEntry['code'. $paramCount] ) )
  343. {
  344. $code .= str_replace( $replaceMap, $replacementMap, $mapEntry['code' . $paramCount] ) . "\n";
  345. }
  346. else
  347. {
  348. $code .= str_replace( $replaceMap, $replacementMap, $mapEntry['code'] ) . "\n";
  349. }
  350. }
  351. $newElements[] = eZTemplateNodeTool::createCodePieceElement( $code, $values );
  352. return $newElements;
  353. }
  354. /*!
  355. * \private
  356. */
  357. function wash( $operatorValue, $tpl, $type = 'xhtml' )
  358. {
  359. switch ( $type )
  360. {
  361. case "xhtml":
  362. {
  363. $operatorValue = htmlspecialchars( $operatorValue );
  364. } break;
  365. case "email":
  366. {
  367. $ini = $tpl->ini();
  368. $dotText = $ini->variable( 'WashSettings', 'EmailDotText' );
  369. $atText = $ini->variable( 'WashSettings', 'EmailAtText' );
  370. $operatorValue = str_replace( array( '.',
  371. '@' ),
  372. array( $dotText,
  373. $atText ),
  374. $operatorValue );
  375. } break;
  376. case 'pdf':
  377. {
  378. $operatorValue = str_replace( array( ' ', // use default callback functions in ezpdf library
  379. "\r\n",
  380. "\t" ),
  381. array( '<C:callSpace>',
  382. '<C:callNewLine>',
  383. '<C:callTab>' ),
  384. $operatorValue );
  385. $operatorValue = str_replace( "\n", '<C:callNewLine>', $operatorValue );
  386. } break;
  387. case 'javascript':
  388. {
  389. $operatorValue = str_replace( array( "\\", "\"", "'"),
  390. array( "\\\\", "\\042", "\\047" ) , $operatorValue );
  391. } break;
  392. }
  393. return $operatorValue;
  394. }
  395. function washTransformation( $operatorName, $node, $tpl, $resourceData,
  396. $element, $lastElement, $elementList, $elementTree, &$parameters )
  397. {
  398. $values = array();
  399. $tmpVarCount = 0;
  400. $newElements = array();
  401. $paramCount = count( $parameters );
  402. if ( $paramCount > 2 )
  403. {
  404. return false;
  405. }
  406. $allStatic = true;
  407. $staticValues = array();
  408. for ($i = 0; $i < $paramCount; $i++)
  409. {
  410. if ( eZTemplateNodeTool::isConstantElement( $parameters[$i] ) )
  411. {
  412. $staticValues[$i] = eZTemplateNodeTool::elementConstantValue( $parameters[$i] );
  413. }
  414. else
  415. {
  416. $allStatic = false;
  417. }
  418. }
  419. /* Do optimalizations for 'xhtml' case */
  420. if ( $allStatic ) {
  421. if ( $paramCount == 1 )
  422. {
  423. $type = 'xhtml';
  424. }
  425. else
  426. {
  427. $type = $staticValues[1];
  428. }
  429. $code = "%output% = '" . addcslashes( $this->wash( $staticValues[0], $tpl, $type ), "'\\" ) . "' ;\n";
  430. }
  431. /* XHTML: Type is static, input is not */
  432. else if ( ( $paramCount == 1 ) || ( ( $paramCount == 2 ) && isset( $staticValues[1] ) && ( $staticValues[1] == 'xhtml' ) ) )
  433. {
  434. $values[] = $parameters[0];
  435. $code = "%output% = htmlspecialchars( %1% );\n";
  436. }
  437. /* PDF: Type is static, input is not static */
  438. else if ( ( $paramCount == 2 ) && isset( $staticValues[1] ) && ( $staticValues[1] == 'pdf' ) )
  439. {
  440. $values[] = $parameters[0];
  441. $tmpVarCount = 1;
  442. $code = '%tmp1% = str_replace( array( " ", "\r\n", "\t" ), array( "<C:callSpace>", "<C:callNewLine>", "<C:callTab>" ), %1% );'. "\n";
  443. $code .= '%output% = str_replace( "\n", "<C:callNewLine>", %tmp1% );'."\n";
  444. }
  445. /* MAIL: Type is static, input is not static */
  446. else if ( ( $paramCount == 2 ) && isset( $staticValues[1] ) && ( $staticValues[1] == 'email' ) )
  447. {
  448. $ini = $tpl->ini();
  449. $dotText = addcslashes( $ini->variable( 'WashSettings', 'EmailDotText' ), "'" );
  450. $atText = addcslashes( $ini->variable( 'WashSettings', 'EmailAtText' ), "'" );
  451. $values[] = $parameters[0];
  452. $code = "%output% = str_replace( array( '.', '@' ), array( '$dotText', '$atText' ), %1% );\n";
  453. }
  454. /* JAVASCRIPT: Type is static, input is not static */
  455. else if ( ( $paramCount == 2 ) && isset( $staticValues[1] ) && ( $staticValues[1] == 'javascript' ) )
  456. {
  457. $values[] = $parameters[0];
  458. $code = '%output% = str_replace( array( "\\\\", "\"", "\'" ),
  459. array( "\\\\\\\\", "\\\\042", "\\\\047" ) , %1% ); ';
  460. }
  461. else /* No compiling for the rest cases */
  462. {
  463. return false;
  464. }
  465. $newElements[] = eZTemplateNodeTool::createCodePieceElement( $code, $values, false, $tmpVarCount );
  466. return $newElements;
  467. }
  468. /*
  469. The modify function takes care of the various operations.
  470. */
  471. function modify( $tpl,
  472. $operatorName,
  473. $operatorParameters,
  474. $rootNamespace,
  475. $currentNamespace,
  476. &$operatorValue,
  477. $namedParameters,
  478. $placement )
  479. {
  480. switch ( $operatorName )
  481. {
  482. // Convert all alphabetical chars of operatorvalue to uppercase.
  483. case $this->UpcaseName:
  484. {
  485. $funcName = function_exists( 'mb_strtoupper' ) ? 'mb_strtoupper' : 'strtoupper';
  486. $operatorValue = $funcName( $operatorValue );
  487. } break;
  488. // Convert all alphabetical chars of operatorvalue to lowercase.
  489. case $this->DowncaseName:
  490. {
  491. $funcName = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  492. $operatorValue = $funcName( $operatorValue );
  493. } break;
  494. // Count and return the number of words in operatorvalue.
  495. case $this->Count_wordsName:
  496. {
  497. $operatorValue = preg_match_all( "#(\w+)#", $operatorValue, $dummy_match );
  498. }break;
  499. // Count and return the number of chars in operatorvalue.
  500. case $this->Count_charsName:
  501. {
  502. $funcName = function_exists( 'mb_strlen' ) ? 'mb_strlen' : 'strlen';
  503. $operatorValue = $funcName( $operatorValue );
  504. }break;
  505. // Insert HTML line breaks before newlines.
  506. case $this->BreakName:
  507. {
  508. $operatorValue = nl2br( $operatorValue );
  509. }break;
  510. // Wrap line (insert newlines).
  511. case $this->WrapName:
  512. {
  513. $parameters = array( $operatorValue );
  514. if ( $namedParameters['wrap_at_position'] )
  515. {
  516. $parameters[] = $namedParameters['wrap_at_position'];
  517. if ( $namedParameters['break_sequence'] )
  518. {
  519. $parameters[] = $namedParameters['break_sequence'];
  520. if ( $namedParameters['cut'] )
  521. {
  522. $parameters[] = $namedParameters['cut'];
  523. }
  524. }
  525. }
  526. $operatorValue = call_user_func_array( 'wordwrap', $parameters );
  527. }break;
  528. // Convert the first character to uppercase.
  529. case $this->UpfirstName:
  530. {
  531. $i18nIni = eZINI::instance( 'i18n.ini' );
  532. $hasMBString = ( $i18nIni->variable( 'CharacterSettings', 'MBStringExtension' ) == 'enabled' and
  533. function_exists( "mb_strtoupper" ) and
  534. function_exists( "mb_substr" ) and
  535. function_exists( "mb_strlen" ) );
  536. if ( $hasMBString )
  537. {
  538. $encoding = eZTextCodec::internalCharset();
  539. $firstLetter = mb_strtoupper( mb_substr( $operatorValue, 0, 1, $encoding ), $encoding );
  540. $remainingText = mb_substr( $operatorValue, 1, mb_strlen( $operatorValue, $encoding ), $encoding );
  541. $operatorValue = $firstLetter . $remainingText;
  542. }
  543. else
  544. {
  545. $operatorValue = ucfirst( $operatorValue );
  546. }
  547. }break;
  548. // Simplify / transform multiple consecutive characters into one.
  549. case $this->SimplifyName:
  550. {
  551. $simplifyCharacter = $namedParameters['char'];
  552. if ( $namedParameters['char'] === false )
  553. {
  554. $replace_this = "/ {2,}/";
  555. $simplifyCharacter = ' ';
  556. }
  557. else
  558. {
  559. $replace_this = "/". $simplifyCharacter ."{2,}/";
  560. }
  561. $operatorValue = preg_replace( $replace_this, $simplifyCharacter, $operatorValue );
  562. }break;
  563. // Convert all first characters [in all words] to uppercase.
  564. case $this->UpwordName:
  565. {
  566. $i18nIni = eZINI::instance( 'i18n.ini' );
  567. $hasMBString = ( $i18nIni->variable( 'CharacterSettings', 'MBStringExtension' ) == 'enabled' and
  568. function_exists( "mb_strtoupper" ) and
  569. function_exists( "mb_substr" ) and
  570. function_exists( "mb_strlen" ) );
  571. if ( $hasMBString )
  572. {
  573. $encoding = eZTextCodec::internalCharset();
  574. $words = explode( " ", $operatorValue );
  575. $newString = array();
  576. foreach ( $words as $word )
  577. {
  578. $firstLetter = mb_strtoupper( mb_substr( $word, 0, 1, $encoding ), $encoding );
  579. $remainingText = mb_substr( $word, 1, mb_strlen( $word, $encoding ), $encoding );
  580. $newString[]= $firstLetter . $remainingText;
  581. }
  582. $operatorValue = implode( " ", $newString );
  583. unset( $newString, $words );
  584. }
  585. else
  586. {
  587. $operatorValue = ucwords( $operatorValue );
  588. }
  589. }break;
  590. // Strip whitespace from the beginning and end of a string.
  591. case $this->TrimName:
  592. {
  593. if ( $namedParameters['chars_to_remove'] === false )
  594. $operatorValue = trim( $operatorValue );
  595. else
  596. $operatorValue = trim( $operatorValue, $namedParameters['chars_to_remove'] );
  597. }break;
  598. // Pad...
  599. case $this->PadName:
  600. {
  601. if (strlen( $operatorValue ) < $namedParameters['desired_length'])
  602. {
  603. $operatorValue = str_pad( $operatorValue,
  604. $namedParameters['desired_length'],
  605. $namedParameters['pad_sequence'] );
  606. }
  607. }break;
  608. // Shorten string [default or specified length, length=text+"..."] and add '...'
  609. case $this->ShortenName:
  610. {
  611. $strlenFunc = function_exists( 'mb_strlen' ) ? 'mb_strlen' : 'strlen';
  612. $substrFunc = function_exists( 'mb_substr' ) ? 'mb_substr' : 'substr';
  613. if ( $strlenFunc( $operatorValue ) > $namedParameters['chars_to_keep'] )
  614. {
  615. $operatorLength = $strlenFunc( $operatorValue );
  616. if ( $namedParameters['trim_type'] === 'middle' )
  617. {
  618. $appendedStrLen = $strlenFunc( $namedParameters['str_to_append'] );
  619. if ( $namedParameters['chars_to_keep'] > $appendedStrLen )
  620. {
  621. $chop = $namedParameters['chars_to_keep'] - $appendedStrLen;
  622. $middlePos = (int)($chop / 2);
  623. $leftPartLength = $middlePos;
  624. $rightPartLength = $chop - $middlePos;
  625. $operatorValue = trim( $substrFunc( $operatorValue, 0, $leftPartLength ) . $namedParameters['str_to_append'] . $substrFunc( $operatorValue, $operatorLength - $rightPartLength, $rightPartLength ) );
  626. }
  627. else
  628. {
  629. $operatorValue = $namedParameters['str_to_append'];
  630. }
  631. }
  632. else // default: trim_type === 'right'
  633. {
  634. $chop = $namedParameters['chars_to_keep'] - $strlenFunc( $namedParameters['str_to_append'] );
  635. $operatorValue = $substrFunc( $operatorValue, 0, $chop );
  636. $operatorValue = trim( $operatorValue );
  637. if ( $operatorLength > $chop )
  638. $operatorValue = $operatorValue.$namedParameters['str_to_append'];
  639. }
  640. }
  641. }break;
  642. // Wash (translate strings to non-spammable text):
  643. case $this->WashName:
  644. {
  645. $type = $namedParameters['type'];
  646. $operatorValue = $this->wash( $operatorValue, $tpl, $type );
  647. }break;
  648. // Ord (translate a unicode string to actual unicode id/numbers):
  649. case $this->OrdName:
  650. {
  651. $codec = eZTextCodec::instance( false, 'unicode' );
  652. $output = $codec->convertString( $operatorValue );
  653. $operatorValue = $output;
  654. }break;
  655. // Chr (generate unicode characters based on input):
  656. case $this->ChrName:
  657. {
  658. $codec = eZTextCodec::instance( 'unicode', false );
  659. $output = $codec->convertString( $operatorValue );
  660. $operatorValue = $output;
  661. }break;
  662. // Default case: something went wrong - unknown things...
  663. default:
  664. {
  665. $tpl->warning( $operatorName, "Unknown string type '$type'", $placement );
  666. } break;
  667. }
  668. }
  669. /// The array of operators, used for registering operators
  670. public $Operators;
  671. }
  672. ?>