| 1: | <?php
|
| 2: | |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: | |
| 10: | |
| 11: | |
| 12: | |
| 13: | |
| 14: | |
| 15: | |
| 16: | |
| 17: | |
| 18: |
|
| 19: |
|
| 20: | defined('XOOPS_ROOT_PATH') || exit('Restricted access');
|
| 21: |
|
| 22: | |
| 23: | |
| 24: | |
| 25: | |
| 26: | |
| 27: | |
| 28: | |
| 29: | |
| 30: | |
| 31: | |
| 32: | |
| 33: | |
| 34: | |
| 35: | |
| 36: | |
| 37: | |
| 38: | |
| 39: | |
| 40: | |
| 41: | |
| 42: | |
| 43: | |
| 44: | |
| 45: | |
| 46: | |
| 47: | |
| 48: | |
| 49: | |
| 50: | |
| 51: | |
| 52: | |
| 53: | |
| 54: | |
| 55: | |
| 56: | |
| 57: | |
| 58: | |
| 59: | |
| 60: | |
| 61: | |
| 62: | |
| 63: | |
| 64: | |
| 65: | |
| 66: | |
| 67: | |
| 68: | |
| 69: | |
| 70: | |
| 71: |
|
| 72: | class XoopsMediaUploader
|
| 73: | {
|
| 74: | |
| 75: | |
| 76: |
|
| 77: |
|
| 78: | public $allowUnknownTypes = false;
|
| 79: | public $mediaName;
|
| 80: | public $mediaType;
|
| 81: | public $mediaSize;
|
| 82: | public $mediaTmpName;
|
| 83: | public $mediaError;
|
| 84: | public $mediaRealType = '';
|
| 85: | public $uploadDir = '';
|
| 86: | public $allowedMimeTypes = array();
|
| 87: | public $deniedMimeTypes = array(
|
| 88: | 'application/x-httpd-php');
|
| 89: | public $maxFileSize = 0;
|
| 90: | public $maxWidth;
|
| 91: | public $maxHeight;
|
| 92: | public $targetFileName;
|
| 93: | public $prefix;
|
| 94: | public $errors = array();
|
| 95: | public $savedDestination;
|
| 96: | public $savedFileName;
|
| 97: | public $extensionToMime = array();
|
| 98: | public $checkImageType = true;
|
| 99: | public $extensionsToBeSanitized = array(
|
| 100: | 'php',
|
| 101: | 'phtml',
|
| 102: | 'phtm',
|
| 103: | 'php3',
|
| 104: | 'php4',
|
| 105: | 'cgi',
|
| 106: | 'pl',
|
| 107: | 'asp',
|
| 108: | 'php5',
|
| 109: | 'php7',
|
| 110: | );
|
| 111: |
|
| 112: | public $imageExtensions = array(
|
| 113: | 1 => 'gif',
|
| 114: | 2 => 'jpg',
|
| 115: | 3 => 'png',
|
| 116: | 4 => 'swf',
|
| 117: | 5 => 'psd',
|
| 118: | 6 => 'bmp',
|
| 119: | 7 => 'tif',
|
| 120: | 8 => 'tif',
|
| 121: | 9 => 'jpc',
|
| 122: | 10 => 'jp2',
|
| 123: | 11 => 'jpx',
|
| 124: | 12 => 'jb2',
|
| 125: | 13 => 'swc',
|
| 126: | 14 => 'iff',
|
| 127: | 15 => 'wbmp',
|
| 128: | 16 => 'xbm',
|
| 129: | 17 => 'webp');
|
| 130: | public $randomFilename = false;
|
| 131: |
|
| 132: | |
| 133: | |
| 134: | |
| 135: | |
| 136: | |
| 137: | |
| 138: | |
| 139: | |
| 140: | |
| 141: |
|
| 142: |
|
| 143: | public function __construct($uploadDir, $allowedMimeTypes, $maxFileSize = 0, $maxWidth = null, $maxHeight = null, $randomFilename = false)
|
| 144: | {
|
| 145: | $this->extensionToMime = include $GLOBALS['xoops']->path('include/mimetypes.inc.php');
|
| 146: | if (!is_array($this->extensionToMime)) {
|
| 147: | $this->extensionToMime = array();
|
| 148: |
|
| 149: | return false;
|
| 150: | }
|
| 151: | if (is_array($allowedMimeTypes)) {
|
| 152: | $this->allowedMimeTypes =& $allowedMimeTypes;
|
| 153: | }
|
| 154: | $this->uploadDir = $uploadDir;
|
| 155: |
|
| 156: | $limits = array();
|
| 157: | $limits = $this->arrayPushIfPositive($limits, $maxFileSize);
|
| 158: | $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('upload_max_filesize')));
|
| 159: | $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('post_max_size')));
|
| 160: | $limits = $this->arrayPushIfPositive($limits, $this->return_bytes(ini_get('memory_limit')));
|
| 161: | $this->maxFileSize = min($limits);
|
| 162: |
|
| 163: | if (isset($maxWidth)) {
|
| 164: | $this->maxWidth = (int)$maxWidth;
|
| 165: | }
|
| 166: | if (isset($maxHeight)) {
|
| 167: | $this->maxHeight = (int)$maxHeight;
|
| 168: | }
|
| 169: | if (isset($randomFilename)) {
|
| 170: | $this->randomFilename = $randomFilename;
|
| 171: | }
|
| 172: | if (!include_once $GLOBALS['xoops']->path('language/' . $GLOBALS['xoopsConfig']['language'] . '/uploader.php')) {
|
| 173: | include_once $GLOBALS['xoops']->path('language/english/uploader.php');
|
| 174: | }
|
| 175: | }
|
| 176: |
|
| 177: | |
| 178: | |
| 179: | |
| 180: | |
| 181: | |
| 182: | |
| 183: |
|
| 184: | public function return_bytes($size_str)
|
| 185: | {
|
| 186: | switch (substr($size_str, -1)) {
|
| 187: | case 'K':
|
| 188: | case 'k':
|
| 189: | return (int)$size_str * 1024;
|
| 190: | case 'M':
|
| 191: | case 'm':
|
| 192: | return (int)$size_str * 1048576;
|
| 193: | case 'G':
|
| 194: | case 'g':
|
| 195: | return (int)$size_str * 1073741824;
|
| 196: | default:
|
| 197: | return $size_str;
|
| 198: | }
|
| 199: | }
|
| 200: |
|
| 201: | |
| 202: | |
| 203: | |
| 204: | |
| 205: | |
| 206: |
|
| 207: | public function countMedia($media_name) {
|
| 208: | if (!isset($_FILES[$media_name])) {
|
| 209: | $this->setErrors(_ER_UP_FILENOTFOUND);
|
| 210: | return false;
|
| 211: | }
|
| 212: | return count($_FILES[$media_name]['name']);
|
| 213: | }
|
| 214: |
|
| 215: | |
| 216: | |
| 217: | |
| 218: | |
| 219: | |
| 220: | |
| 221: |
|
| 222: | public function fetchMedia($media_name, $index = null)
|
| 223: | {
|
| 224: | if (empty($this->extensionToMime)) {
|
| 225: | $this->setErrors(_ER_UP_MIMETYPELOAD);
|
| 226: |
|
| 227: | return false;
|
| 228: | }
|
| 229: | if (!isset($_FILES[$media_name])) {
|
| 230: | $this->setErrors(_ER_UP_FILENOTFOUND);
|
| 231: |
|
| 232: | return false;
|
| 233: | } elseif (is_array($_FILES[$media_name]['name']) && isset($index)) {
|
| 234: | $index = (int)$index;
|
| 235: | $this->mediaName = @get_magic_quotes_gpc() ? stripslashes($_FILES[$media_name]['name'][$index]) : $_FILES[$media_name]['name'][$index];
|
| 236: | if ($this->randomFilename) {
|
| 237: | $unique = uniqid('', true);
|
| 238: | $this->targetFileName = '' . $unique . '--' . $this->mediaName;
|
| 239: | }
|
| 240: | $this->mediaType = $_FILES[$media_name]['type'][$index];
|
| 241: | $this->mediaSize = $_FILES[$media_name]['size'][$index];
|
| 242: | $this->mediaTmpName = $_FILES[$media_name]['tmp_name'][$index];
|
| 243: | $this->mediaError = !empty($_FILES[$media_name]['error'][$index]) ? $_FILES[$media_name]['error'][$index] : 0;
|
| 244: | } elseif (is_array($_FILES[$media_name]['name']) && !isset($index)) {
|
| 245: | $this->setErrors(_ER_UP_INDEXNOTSET);
|
| 246: |
|
| 247: | return false;
|
| 248: | } else {
|
| 249: | $media_name =& $_FILES[$media_name];
|
| 250: | $this->mediaName = @get_magic_quotes_gpc() ? stripslashes($media_name['name']) : $media_name['name'];
|
| 251: | if ($this->randomFilename) {
|
| 252: | $unique = uniqid('', true);
|
| 253: | $this->targetFileName = '' . $unique . '--' . $this->mediaName;
|
| 254: | }
|
| 255: | $this->mediaType = $media_name['type'];
|
| 256: | $this->mediaSize = $media_name['size'];
|
| 257: | $this->mediaTmpName = $media_name['tmp_name'];
|
| 258: | $this->mediaError = !empty($media_name['error']) ? $media_name['error'] : 0;
|
| 259: | }
|
| 260: |
|
| 261: | if (($ext = strrpos($this->mediaName, '.')) !== false) {
|
| 262: | $ext = strtolower(substr($this->mediaName, $ext + 1));
|
| 263: | if (isset($this->extensionToMime[$ext])) {
|
| 264: | $this->mediaRealType = $this->extensionToMime[$ext];
|
| 265: | }
|
| 266: | }
|
| 267: | $this->errors = array();
|
| 268: | if ($this->mediaError > 0) {
|
| 269: | switch($this->mediaError){
|
| 270: | case UPLOAD_ERR_INI_SIZE:
|
| 271: | $this->setErrors(_ER_UP_INISIZE);
|
| 272: | return false;
|
| 273: | break;
|
| 274: | case UPLOAD_ERR_FORM_SIZE:
|
| 275: | $this->setErrors(_ER_UP_FORMSIZE);
|
| 276: | return false;
|
| 277: | break;
|
| 278: | case UPLOAD_ERR_PARTIAL:
|
| 279: | $this->setErrors(_ER_UP_PARTIAL);
|
| 280: | return false;
|
| 281: | break;
|
| 282: | case UPLOAD_ERR_NO_FILE:
|
| 283: | $this->setErrors(_ER_UP_NOFILE);
|
| 284: | return false;
|
| 285: | break;
|
| 286: | case UPLOAD_ERR_NO_TMP_DIR:
|
| 287: | $this->setErrors(_ER_UP_NOTMPDIR);
|
| 288: | return false;
|
| 289: | break;
|
| 290: | case UPLOAD_ERR_CANT_WRITE:
|
| 291: | $this->setErrors(_ER_UP_CANTWRITE);
|
| 292: | return false;
|
| 293: | break;
|
| 294: | case UPLOAD_ERR_EXTENSION:
|
| 295: | $this->setErrors(_ER_UP_EXTENSION);
|
| 296: | return false;
|
| 297: | break;
|
| 298: | default:
|
| 299: | $this->setErrors(_ER_UP_UNKNOWN);
|
| 300: | return false;
|
| 301: | break;
|
| 302: | }
|
| 303: | }
|
| 304: |
|
| 305: | if ((int)$this->mediaSize < 0) {
|
| 306: | $this->setErrors(_ER_UP_INVALIDFILESIZE);
|
| 307: |
|
| 308: | return false;
|
| 309: | }
|
| 310: | if ($this->mediaName == '') {
|
| 311: | $this->setErrors(_ER_UP_FILENAMEEMPTY);
|
| 312: |
|
| 313: | return false;
|
| 314: | }
|
| 315: | if ($this->mediaTmpName === 'none' || !is_uploaded_file($this->mediaTmpName)) {
|
| 316: | $this->setErrors(_ER_UP_NOFILEUPLOADED);
|
| 317: |
|
| 318: | return false;
|
| 319: | }
|
| 320: |
|
| 321: | return true;
|
| 322: | }
|
| 323: |
|
| 324: | |
| 325: | |
| 326: | |
| 327: | |
| 328: |
|
| 329: | public function setTargetFileName($value)
|
| 330: | {
|
| 331: | $this->targetFileName = (string)trim($value);
|
| 332: | }
|
| 333: |
|
| 334: | |
| 335: | |
| 336: | |
| 337: | |
| 338: |
|
| 339: | public function setPrefix($value)
|
| 340: | {
|
| 341: | $this->prefix = (string)trim($value);
|
| 342: | }
|
| 343: |
|
| 344: | |
| 345: | |
| 346: | |
| 347: | |
| 348: |
|
| 349: | public function getMediaName()
|
| 350: | {
|
| 351: | return $this->mediaName;
|
| 352: | }
|
| 353: |
|
| 354: | |
| 355: | |
| 356: | |
| 357: | |
| 358: |
|
| 359: | public function getMediaType()
|
| 360: | {
|
| 361: | return $this->mediaType;
|
| 362: | }
|
| 363: |
|
| 364: | |
| 365: | |
| 366: | |
| 367: | |
| 368: |
|
| 369: | public function getMediaSize()
|
| 370: | {
|
| 371: | return $this->mediaSize;
|
| 372: | }
|
| 373: |
|
| 374: | |
| 375: | |
| 376: | |
| 377: | |
| 378: |
|
| 379: | public function getMediaTmpName()
|
| 380: | {
|
| 381: | return $this->mediaTmpName;
|
| 382: | }
|
| 383: |
|
| 384: | |
| 385: | |
| 386: | |
| 387: | |
| 388: |
|
| 389: | public function getSavedFileName()
|
| 390: | {
|
| 391: | return $this->savedFileName;
|
| 392: | }
|
| 393: |
|
| 394: | |
| 395: | |
| 396: | |
| 397: | |
| 398: |
|
| 399: | public function getSavedDestination()
|
| 400: | {
|
| 401: | return $this->savedDestination;
|
| 402: | }
|
| 403: |
|
| 404: | |
| 405: | |
| 406: | |
| 407: | |
| 408: | |
| 409: |
|
| 410: | public function upload($chmod = 0644)
|
| 411: | {
|
| 412: | if ($this->uploadDir == '') {
|
| 413: | $this->setErrors(_ER_UP_UPLOADDIRNOTSET);
|
| 414: |
|
| 415: | return false;
|
| 416: | }
|
| 417: | if (!is_dir($this->uploadDir)) {
|
| 418: | $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIR, $this->uploadDir));
|
| 419: |
|
| 420: | return false;
|
| 421: | }
|
| 422: | if (!is_writable($this->uploadDir)) {
|
| 423: | $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIRWRITE, $this->uploadDir));
|
| 424: |
|
| 425: | return false;
|
| 426: | }
|
| 427: | $this->sanitizeMultipleExtensions();
|
| 428: |
|
| 429: | if (!$this->checkMaxFileSize()) {
|
| 430: | return false;
|
| 431: | }
|
| 432: | if (!$this->checkMaxWidth()) {
|
| 433: | return false;
|
| 434: | }
|
| 435: | if (!$this->checkMaxHeight()) {
|
| 436: | return false;
|
| 437: | }
|
| 438: | if (!$this->checkMimeType()) {
|
| 439: | return false;
|
| 440: | }
|
| 441: | if (!$this->checkImageType()) {
|
| 442: | return false;
|
| 443: | }
|
| 444: | if (count($this->errors) > 0) {
|
| 445: | return false;
|
| 446: | }
|
| 447: |
|
| 448: | return $this->_copyFile($chmod);
|
| 449: | }
|
| 450: |
|
| 451: | |
| 452: | |
| 453: | |
| 454: | |
| 455: | |
| 456: |
|
| 457: | public function _copyFile($chmod)
|
| 458: | {
|
| 459: | $matched = array();
|
| 460: | if (!preg_match("/\.([a-zA-Z0-9]+)$/", $this->mediaName, $matched)) {
|
| 461: | $this->setErrors(_ER_UP_INVALIDFILENAME);
|
| 462: |
|
| 463: | return false;
|
| 464: | }
|
| 465: | if (isset($this->targetFileName)) {
|
| 466: | $this->savedFileName = $this->targetFileName;
|
| 467: | } elseif (isset($this->prefix)) {
|
| 468: | $this->savedFileName = uniqid($this->prefix, true) . '.' . strtolower($matched[1]);
|
| 469: | } else {
|
| 470: | $this->savedFileName = strtolower($this->mediaName);
|
| 471: | }
|
| 472: |
|
| 473: | $this->savedFileName = iconv('UTF-8', 'ASCII//TRANSLIT', $this->savedFileName);
|
| 474: | $this->savedFileName = preg_replace('!\s+!', '_', $this->savedFileName);
|
| 475: | $this->savedFileName = preg_replace("/[^a-zA-Z0-9\._-]/", '', $this->savedFileName);
|
| 476: |
|
| 477: | $this->savedDestination = $this->uploadDir . '/' . $this->savedFileName;
|
| 478: | if (!move_uploaded_file($this->mediaTmpName, $this->savedDestination)) {
|
| 479: | $this->setErrors(sprintf(_ER_UP_FAILEDSAVEFILE, $this->savedDestination));
|
| 480: |
|
| 481: | return false;
|
| 482: | }
|
| 483: |
|
| 484: | $ext = strtolower(substr(strrchr($this->savedDestination, '.'), 1));
|
| 485: | if (in_array($ext, $this->imageExtensions)) {
|
| 486: | $info = @getimagesize($this->savedDestination);
|
| 487: | if ($info === false || $this->imageExtensions[(int)$info[2]] != $ext) {
|
| 488: | $this->setErrors(_ER_UP_SUSPICIOUSREFUSED);
|
| 489: | @unlink($this->savedDestination);
|
| 490: |
|
| 491: | return false;
|
| 492: | }
|
| 493: | }
|
| 494: | @chmod($this->savedDestination, $chmod);
|
| 495: |
|
| 496: | return true;
|
| 497: | }
|
| 498: |
|
| 499: | |
| 500: | |
| 501: | |
| 502: | |
| 503: |
|
| 504: | public function checkMaxFileSize()
|
| 505: | {
|
| 506: | if (!isset($this->maxFileSize)) {
|
| 507: | return true;
|
| 508: | }
|
| 509: | if ($this->mediaSize > $this->maxFileSize) {
|
| 510: | $this->setErrors(sprintf(_ER_UP_FILESIZETOOLARGE, $this->maxFileSize, $this->mediaSize));
|
| 511: |
|
| 512: | return false;
|
| 513: | }
|
| 514: |
|
| 515: | return true;
|
| 516: | }
|
| 517: |
|
| 518: | |
| 519: | |
| 520: | |
| 521: | |
| 522: |
|
| 523: | public function checkMaxWidth()
|
| 524: | {
|
| 525: | if (!isset($this->maxWidth)) {
|
| 526: | return true;
|
| 527: | }
|
| 528: | if (false !== $dimension = getimagesize($this->mediaTmpName)) {
|
| 529: | if ($dimension[0] > $this->maxWidth) {
|
| 530: | $this->setErrors(sprintf(_ER_UP_FILEWIDTHTOOLARGE, $this->maxWidth, $dimension[0]));
|
| 531: |
|
| 532: | return false;
|
| 533: | }
|
| 534: | } else {
|
| 535: | trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
|
| 536: | }
|
| 537: |
|
| 538: | return true;
|
| 539: | }
|
| 540: |
|
| 541: | |
| 542: | |
| 543: | |
| 544: | |
| 545: |
|
| 546: | public function checkMaxHeight()
|
| 547: | {
|
| 548: | if (!isset($this->maxHeight)) {
|
| 549: | return true;
|
| 550: | }
|
| 551: | if (false !== $dimension = getimagesize($this->mediaTmpName)) {
|
| 552: | if ($dimension[1] > $this->maxHeight) {
|
| 553: | $this->setErrors(sprintf(_ER_UP_FILEHEIGHTTOOLARGE, $this->maxHeight, $dimension[1]));
|
| 554: |
|
| 555: | return false;
|
| 556: | }
|
| 557: | } else {
|
| 558: | trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
|
| 559: | }
|
| 560: |
|
| 561: | return true;
|
| 562: | }
|
| 563: |
|
| 564: | |
| 565: | |
| 566: | |
| 567: | |
| 568: |
|
| 569: | public function checkMimeType()
|
| 570: | {
|
| 571: |
|
| 572: | $structureCheck = (bool) preg_match('/^\w+\/[-+.\w]+$/', $this->mediaType);
|
| 573: | if (false === $structureCheck) {
|
| 574: | $this->mediaType = 'invalid';
|
| 575: | $this->setErrors(_ER_UP_UNKNOWNFILETYPEREJECTED);
|
| 576: | return false;
|
| 577: | }
|
| 578: |
|
| 579: | if (empty($this->mediaRealType) && empty($this->allowUnknownTypes)) {
|
| 580: | $this->setErrors(_ER_UP_UNKNOWNFILETYPEREJECTED);
|
| 581: |
|
| 582: | return false;
|
| 583: | }
|
| 584: |
|
| 585: | if ((!empty($this->allowedMimeTypes) && !in_array($this->mediaRealType, $this->allowedMimeTypes)) || (!empty($this->deniedMimeTypes) && in_array($this->mediaRealType, $this->deniedMimeTypes))) {
|
| 586: | $this->setErrors(sprintf(_ER_UP_MIMETYPENOTALLOWED, htmlspecialchars($this->mediaRealType, ENT_QUOTES)));
|
| 587: |
|
| 588: | return false;
|
| 589: | }
|
| 590: |
|
| 591: | return true;
|
| 592: | }
|
| 593: |
|
| 594: | |
| 595: | |
| 596: | |
| 597: | |
| 598: |
|
| 599: | public function checkImageType()
|
| 600: | {
|
| 601: | if (empty($this->checkImageType)) {
|
| 602: | return true;
|
| 603: | }
|
| 604: |
|
| 605: | if (('image' === substr($this->mediaType, 0, strpos($this->mediaType, '/'))) || (!empty($this->mediaRealType) && 'image' === substr($this->mediaRealType, 0, strpos($this->mediaRealType, '/')))) {
|
| 606: | if (!($info = @getimagesize($this->mediaTmpName))) {
|
| 607: | $this->setErrors(_ER_UP_INVALIDIMAGEFILE);
|
| 608: |
|
| 609: | return false;
|
| 610: | }
|
| 611: | }
|
| 612: |
|
| 613: | return true;
|
| 614: | }
|
| 615: |
|
| 616: | |
| 617: | |
| 618: |
|
| 619: | public function sanitizeMultipleExtensions()
|
| 620: | {
|
| 621: | if (empty($this->extensionsToBeSanitized)) {
|
| 622: | return null;
|
| 623: | }
|
| 624: |
|
| 625: | $patterns = array();
|
| 626: | $replaces = array();
|
| 627: | foreach ($this->extensionsToBeSanitized as $ext) {
|
| 628: | $patterns[] = "/\." . preg_quote($ext, '/') . "\./i";
|
| 629: | $replaces[] = '_' . $ext . '.';
|
| 630: | }
|
| 631: | $this->mediaName = preg_replace($patterns, $replaces, $this->mediaName);
|
| 632: | }
|
| 633: |
|
| 634: | |
| 635: | |
| 636: | |
| 637: | |
| 638: |
|
| 639: | public function setErrors($error)
|
| 640: | {
|
| 641: | $this->errors[] = trim($error);
|
| 642: | }
|
| 643: |
|
| 644: | |
| 645: | |
| 646: | |
| 647: | |
| 648: | |
| 649: |
|
| 650: | public function &getErrors($ashtml = true)
|
| 651: | {
|
| 652: | if (!$ashtml) {
|
| 653: | return $this->errors;
|
| 654: | } else {
|
| 655: | $ret = '';
|
| 656: | if (count($this->errors) > 0) {
|
| 657: | $ret = '<h4>' . sprintf(_ER_UP_ERRORSRETURNED, htmlspecialchars($this->mediaName, ENT_QUOTES)) . '</h4>';
|
| 658: | foreach ($this->errors as $error) {
|
| 659: | $ret .= $error . '<br>';
|
| 660: | }
|
| 661: | }
|
| 662: |
|
| 663: | return $ret;
|
| 664: | }
|
| 665: | }
|
| 666: |
|
| 667: | |
| 668: | |
| 669: | |
| 670: | |
| 671: | |
| 672: | |
| 673: | |
| 674: | |
| 675: |
|
| 676: | protected function arrayPushIfPositive($set, $value) {
|
| 677: | if ($value > 0) {
|
| 678: | array_push($set, $value);
|
| 679: | }
|
| 680: | return $set;
|
| 681: | }
|
| 682: | }
|
| 683: | |