Treatment.class.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. require_once(__DIR__.SLASH.'..'.SLASH.'WidgetElement.class.php');
  3. class Treatment extends WidgetElement{
  4. public $source;
  5. public $TABLE_NAME = 'statistic_treatment';
  6. public $javascript = 'function(){stats_element_init("treatment");}';
  7. public $icon = 'fas fa-code';
  8. public $typeLabel = 'Code';
  9. function __construct(){
  10. parent::__construct();
  11. $this->fields['source'] = 'longstring';
  12. $this->fieldMapping = $this->field_mapping($this->fields);
  13. }
  14. function editor(){
  15. if($this->source == '') $this->source = '//tableau des données du précédent élement'.PHP_EOL.'return $data; ';
  16. $html = '<label>
  17. <i class="fas fa-code"></i> Code
  18. </label> - <small>Données disponibles dans <strong>$data</strong>, filtres dans <strong>$filters</strong></small>
  19. <div class="prev-custom-treatment float-right btn btn-small mb-2 ml-2" onclick="stats_element_preview(this,function(){$(\'#output-tab\').click()});"><i class="fas fa-play-circle"></i> Exécuter</div>
  20. <div id="server-status" class="d-inline-block float-right"></div>
  21. <div class="clear"></div>
  22. <textarea id="source">'.$this->source.'</textarea>';
  23. return $html;
  24. }
  25. function preview($data = array(),$filters = array()){
  26. $response = array('data'=>array());
  27. ob_start();
  28. $source = html_entity_decode($this->source,ENT_QUOTES);
  29. $forbidden = self::forbidden($source);
  30. if(count($forbidden)!=0) throw new Exception("Mot clés interdits: ".implode(',',$forbidden));
  31. eval('$method = function($data,$filters){'.$source.'};');
  32. $output = ob_get_clean();
  33. if($output!='') throw new Exception(strip_tags($output));
  34. $response['data'] = $method($data,$filters);
  35. return $response;
  36. }
  37. //Fonction de sécurisation du eval, evite toutes les fonctions non spécifiées ci dessous et toutes les intrcutions type include, class...
  38. public static function forbidden($source){
  39. $ignore_terms = array();
  40. ////Ajoute des fonctions autorisées dans les traitements statistiques ex : $ignore_terms[] = 'Plugin::need'; $ignore_terms[] = 'Business::amount';
  41. Plugin::callHook('statistic_allowed_macro',array(&$ignore_terms));
  42. $source = str_replace($ignore_terms,'',$source);
  43. $tokens = token_get_all('<?php '.$source.' ?>');
  44. $forbiddens = array();
  45. $allowed_functions_generic = array(
  46. 'ucfirst',
  47. 'strto.*',
  48. 'str_.*',
  49. 'date',
  50. 'intval',
  51. 'count',
  52. 'time',
  53. 'array_.*',
  54. 'base64_*',
  55. '.sort',
  56. 'asort',
  57. 'sort',
  58. 'addslashes',
  59. 'json_decode',
  60. 'json_encode',
  61. 'implode',
  62. 'explode',
  63. 'utf8_decode',
  64. 'utf8_encode',
  65. 'html_entity_decode',
  66. 'htmlspecialchars',
  67. 'strip_tags',
  68. 'is_null',
  69. 'is_int',
  70. 'substr',
  71. 'max',
  72. 'true',
  73. 'false',
  74. 'null',
  75. 'strlen',
  76. 'round',
  77. 'in_array',
  78. 'is_numeric'
  79. );
  80. $allowed_functions_specific = array(
  81. '__ROOT__',
  82. 'PLUGIN_PATH',
  83. 'SLASH',
  84. 'html_decode_utf8',
  85. 'Dictionary',
  86. 'fullName',
  87. 'loadAll',
  88. 'getById',
  89. 'bySlug',
  90. 'slugToArray',
  91. 'id',
  92. 'label',
  93. 'value',
  94. 'color',
  95. 'Partner',
  96. 'Product',
  97. 'number_format',
  98. 'display_price',
  99. 'ranking',
  100. 'function'
  101. );
  102. $allowed_functions = array_merge($allowed_functions_generic, $allowed_functions_specific);
  103. foreach($tokens as $i=>$token){
  104. if(is_string($token))continue;
  105. list($id, $text,$line) = $token;
  106. if(in_array($id, array(T_FUNCTION,T_FUNC_C,T_EVAL,T_STRING))){
  107. $allowed = false;
  108. foreach ($allowed_functions as $function) {
  109. preg_match('/'.$function.'/i', $text, $matches);
  110. if(count($matches)!=0){
  111. $allowed = true;
  112. break;
  113. }
  114. }
  115. if(!$allowed) $forbiddens[] = $text.' L'.$line.token_name($id);
  116. }
  117. if(in_array($id, array(
  118. T_INCLUDE,
  119. T_EXTENDS,
  120. T_CLONE,
  121. T_EXIT,
  122. T_GLOBAL,
  123. T_HALT_COMPILER,
  124. T_IMPLEMENTS,
  125. T_INCLUDE_ONCE,
  126. T_REQUIRE,
  127. //T_REQUIRE_ONCE,
  128. T_IMPLEMENTS
  129. )
  130. )){
  131. $forbiddens[] = $text.' L'.$line;
  132. }
  133. }
  134. return $forbiddens;
  135. }
  136. }
  137. ?>