1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 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: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494: 495: 496: 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545: 546: 547: 548: 549: 550: 551: 552: 553: 554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575: 576: 577: 578: 579: 580: 581: 582: 583: 584: 585: 586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603: 604: 605: 606: 607: 608: 609: 610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622: 623: 624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639: 640: 641: 642: 643: 644: 645: 646: 647: 648: 649: 650: 651: 652: 653: 654: 655: 656: 657: 658: 659: 660: 661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672: 673: 674: 675: 676: 677: 678: 679: 680: 681: 682: 683: 684: 685: 686: 687: 688: 689: 690: 691: 692: 693: 694: 695: 696: 697: 698: 699: 700: 701: 702: 703: 704: 705: 706: 707: 708: 709: 710: 711: 712: 713: 714: 715: 716: 717: 718: 719: 720: 721: 722: 723: 724: 725: 726: 727: 728: 729: 730: 731: 732: 733: 734: 735: 736: 737: 738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749: 750: 751: 752: 753: 754: 755: 756: 757: 758: 759: 760: 761: 762: 763: 764: 765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776: 777: 778: 779: 780: 781: 782: 783: 784: 785: 786: 787: 788: 789: 790: 791: 792: 793: 794: 795: 796: 797: 798: 799: 800: 801: 802: 803: 804: 805: 806: 807: 808: 809: 810: 811: 812: 813: 814: 815: 816: 817: 818: 819: 820: 821: 822: 823:
<?php
class Packager_Common_Base {
protected $cfg;
protected $files = [];
protected $cliScriptName;
protected $compilationType = '';
protected $exceptionsMessages = [];
protected $exceptionsTraces = [];
protected $includedFilesCountTillNow = 0;
protected $errorHandlerData = [];
protected $errorResponse = [];
protected $autoLoadedFiles = [];
protected static $templatesExtensions = ['phtml'];
protected static $fileTypesStoringTypes = [
'gzip' => [
'css', 'htc', 'js', 'txt', 'svg'
],
'binary' => [
'ico', 'gif', 'png', 'jpg', 'jpeg',
'zip', 'ttf', 'eot', 'otf', 'woff', 'woff2',
],
'base64' => [
],
'template' => [
'phtml',
],
'text' => [
'ini', 'htm', 'html', 'xml', 'xsd', 'csv',
],
];
protected static $instance;
private static $_cfgDefault = [
'sourcesDir' => '',
'releaseDir' => '',
'releaseFileName' => '/index.php',
'staticCopies' => [],
'excludePatterns' => [],
'includePatterns' => [],
'stringReplacements' => [],
'patternReplacements' => [],
'minifyTemplates' => 0,
'minifyPhp' => 0,
'keepPhpDocComments' => [],
'autoloadingOrderDetection' => TRUE,
'includeFirst' => [],
'includeLast' => [],
'phpFsMode' => 'PHP_PRESERVE_HDD',
'phpFunctionsToReplace' => [],
'phpFunctionsToKeep' => [],
'phpFunctionsToProcess' => [],
'errorReportingLevel' => E_ALL,
];
private static $_htmlStyles = [
'success' => 'html,body{background:#005700;}',
'error' => 'html,body{background:#cd1818;}.xdebug-error,.xdebug-error th,.xdebug-error td{color:#000;text-shadow:none !important;font-size:125%;}.xdebug-var-dump font[color*=cc0000]{background:#fff;text-shadow:none;}',
];
private static $_responseTemplates = [
'text' => "\n======================= %title =======================\n\n\n%h1\n\n\n%content\n\n",
'html' => '<!DOCTYPE HTML><html lang="en-US"><head><meta charset="UTF-8"><title>%title</title><style type="text/css">html,body{margin:30px;font-size:14px;color:#fff;text-align:left;line-height:1.5em;font-weight:bold;font-family:"consolas",courier new,monotype;text-shadow:1px 1px 0 rgba(0,0,0,.4);}h1{font-size:200%;line-height:1.5em;}h2{font-size:150%;line-height:1.5em;}%style</style></head><body><h1>%h1</h1>%content</body></html>',
];
public function __construct ($cfg = []) {
$cfg = is_array($cfg) ? $cfg : [];
foreach (self::$_cfgDefault as $key => $value) {
if (!isset($cfg[$key])) {
$cfg[$key] = self::$_cfgDefault[$key];
}
}
$this->cfg = $cfg;
}
public static function Create ($cfg = []) {
if (!self::$instance) {
$selfClass = get_class();
set_error_handler([$selfClass, 'ErrorHandler']);
set_exception_handler([$selfClass, 'ErrorHandler']);
self::$instance = new static($cfg);
}
return self::$instance;
}
public static function Get ($cfg = []) {
if (!self::$instance) {
self::Create($cfg);
} else {
self::$instance->MergeConfiguration($cfg);
}
return self::$instance;
}
public function SetSourceDir ($fullOrRelativePath = '') {
$sourceDir = ltrim($fullOrRelativePath);
if (is_dir($sourceDir)) {
$this->cfg['sourcesDir'] = realpath($sourceDir);
} else if (is_dir(__DIR__ . $sourceDir)) {
$this->cfg['sourcesDir'] = realpath(__DIR__ . $sourceDir);
}
return $this;
}
public function SetReleaseDir ($fullOrRelativePath = '') {
$this->cfg['releaseDir'] = $fullOrRelativePath;
return $this;
}
public function SetReleaseFileName ($releaseFileName = '/index.php') {
$this->cfg['releaseFileName'] = $releaseFileName;
return $this;
}
public function SetExcludePatterns ($excludePatterns = []) {
if (is_array($excludePatterns)) {
$this->cfg['excludePatterns'] = $excludePatterns;
} else {
$this->cfg['excludePatterns'] = [$excludePatterns];
}
return $this;
}
public function AddExcludePatterns ($excludePatterns = []) {
if (is_array($excludePatterns)) {
$this->MergeConfiguration(['excludePatterns' => $excludePatterns]);
} else {
$this->cfg['excludePatterns'][] = $excludePatterns;
}
return $this;
}
public function SetIncludePatterns ($includePatterns = []) {
if (is_array($includePatterns)) {
$this->cfg['includePatterns'] = $includePatterns;
} else {
$this->cfg['includePatterns'] = [$includePatterns];
}
return $this;
}
public function AddIncludePatterns ($includePatterns = []) {
if (is_array($includePatterns)) {
$this->MergeConfiguration(['includePatterns' => $includePatterns]);
} else {
$this->cfg['includePatterns'][] = $includePatterns;
}
return $this;
}
public function SetPatternReplacements ($patternReplacements = []) {
if (is_array($patternReplacements)) {
$this->cfg['patternReplacements'] = $patternReplacements;
} else {
$this->cfg['patternReplacements'] = [$patternReplacements];
}
return $this;
}
public function AddPatternReplacements ($patternReplacements = []) {
if (is_array($patternReplacements)) {
$this->MergeConfiguration(['patternReplacements' => $patternReplacements]);
} else {
$this->cfg['patternReplacements'][] = $patternReplacements;
}
return $this;
}
public function SetStringReplacements ($stringReplacements = []) {
if (is_array($stringReplacements)) {
$this->cfg['stringReplacements'] = $stringReplacements;
} else {
$this->cfg['stringReplacements'] = [$stringReplacements];
}
return $this;
}
public function AddStringReplacements ($stringReplacements = []) {
if (is_array($stringReplacements)) {
$this->MergeConfiguration(['stringReplacements' => $stringReplacements]);
} else {
$this->cfg['stringReplacements'][] = $stringReplacements;
}
return $this;
}
public function SetMinifyTemplates ($minifyTemplates = TRUE) {
$this->cfg['minifyTemplates'] = (bool)$minifyTemplates;
return $this;
}
public function SetMinifyPhp ($minifyPhp = TRUE) {
$this->cfg['minifyPhp'] = (bool)$minifyPhp;
return $this;
}
public function SetKeepPhpDocComments ($keepPhpDocComments = []) {
$this->cfg['keepPhpDocComments'] = $keepPhpDocComments;
return $this;
}
public function SetIncludeFirst ($includeFirst = []) {
if (is_array($includeFirst)) {
$this->cfg['includeFirst'] = $includeFirst;
} else {
$this->cfg['includeFirst'] = [$includeFirst];
}
return $this;
}
public function AddIncludeFirst ($includeFirst = [], $mode = 'append') {
if (is_array($includeFirst)) {
if ($mode == 'prepend') {
for ($i = count($includeFirst) - 1; $i >= 0; $i--) {
array_unshift($this->cfg['includeFirst'], $includeFirst[$i]);
}
} else {
foreach ($includeFirst as $includeFirstItem) {
$this->cfg['includeFirst'][] = $includeFirstItem;
}
}
} else {
if ($mode == 'prepend') {
array_unshift($this->cfg['includeFirst'], $includeFirst);
} else {
$this->cfg['includeFirst'][] = $includeFirst;
}
}
return $this;
}
public function SetIncludeLast ($includeLast = []) {
if (is_array($includeLast)) {
$this->cfg['includeLast'] = $includeLast;
} else {
$this->cfg['includeLast'] = [$includeLast];
}
return $this;
}
public function AddIncludeLast ($includeLast = [], $mode = 'append') {
if (is_array($includeLast)) {
if ($mode == 'prepend') {
for ($i = count($includeLast) - 1; $i >= 0; $i--) {
array_unshift($this->cfg['includeLast'], $includeLast[$i]);
}
} else {
foreach ($includeLast as $includeLastItem) {
$this->cfg['includeLast'][] = $includeLastItem;
}
}
} else {
if ($mode == 'prepend') {
array_unshift($this->cfg['includeLast'], $includeLast);
} else {
$this->cfg['includeLast'][] = $includeLast;
}
}
return $this;
}
public function SetPhpFileSystemMode ($fsMode = 'PHP_PRESERVE_HDD') {
$this->cfg['phpFsMode'] = $fsMode;
return $this;
}
public function SetAutoloadingOrderDetection ($enabled = TRUE) {
$this->cfg['autoloadingOrderDetection'] = $enabled;
return $this;
}
public function ReplacePhpFunctions () {
$result = isset($this->cfg['phpFunctionsToReplace']) ? $this->cfg['phpFunctionsToReplace'] : [] ;
$this->cfg['phpFunctionsToReplace'] = array_merge($result, func_get_arg(0));
return $this;
}
public function KeepPhpFunctions () {
$result = isset($this->cfg['phpFunctionsToKeep']) ? $this->cfg['phpFunctionsToKeep'] : [] ;
$this->cfg['phpFunctionsToKeep'] = array_merge($result, func_get_arg(0));
return $this;
}
public function SetStaticCopies ($staticCopies = []) {
$this->cfg['staticCopies'] = $staticCopies;
return $this;
}
public function MergeConfiguration ($cfg = []) {
foreach ($cfg as $key1 => & $value1) {
if ($value1 instanceof stdClass) $value1 = (array)$value1;
if (is_array($value1)) {
if (isset($this->cfg[$key1])) {
if ($this->cfg[$key1] instanceof stdClass) {
$this->cfg[$key1] = (array) $this->cfg[$key1];
} else if (!is_array($this->cfg[$key1])) {
$this->cfg[$key1] = [$this->cfg[$key1]];
}
} else {
$this->cfg[$key1] = [];
}
foreach ($value1 as $key2 => & $value2) {
$this->cfg[$key1][$key2] = $value2;
}
} else {
$this->cfg[$key1] = $value1;
}
}
return $this;
}
public function PreRun () {
$this->cfg = (object) $this->cfg;
$this->compilationType = strtoupper(str_replace('Packager_', '', get_class($this)));
$this->_checkCommonConfiguration();
$this->_changeCurrentWorkingDirectoryToProjectRoot();
$this->_setUpStrictExceptionsMode();
return $this;
}
public function PrintFilesToPack () {
$this->PreRun();
$this->completeAllFiles();
$phpFiles = [];
$staticFiles = [];
foreach($this->files->all as $path => $fileItem){
if ($fileItem->extension == 'php') {
$phpFiles[] = $path;
} else {
$staticFiles[] = $path;
}
}
$this->files->php = $phpFiles;
$this->files->static = $staticFiles;
unset($this->files->all);
$this->notify("Files to pack notification");
}
protected static function decodeJson (& $cUrlContentStr) {
$result = (object) [
'success' => FALSE,
'data' => NULL,
'message' => '',
];
$jsonData = json_decode($cUrlContentStr);
if (json_last_error() == JSON_ERROR_NONE) {
$result = $jsonData;
$result->type = 'json';
} else {
$result->message = "Json decode error.";
$result->data = $cUrlContentStr;
$result->type = 'html';
}
return $result;
}
public static function ErrorHandler ($severity = NULL, $message = NULL, $file = NULL, $line = NULL, $context = NULL) {
$backTrace = debug_backtrace();
foreach ($backTrace as & $backTraceItem) {
unset($backTraceItem['args'], $backTraceItem['object']);
}
ob_start();
echo '<pre>';
var_dump($backTrace);
var_dump(error_get_last());
var_dump(func_get_args());
echo '</pre>';
$content = ob_get_clean();
self::$instance->errorHandlerData = func_get_args();
self::$instance->exceptionsTraces = $backTrace;
if (isset($backTrace[count($backTrace) - 2])) {
$semiFinalBacktraceRec = (object) $backTrace[count($backTrace) - 2];
if ($semiFinalBacktraceRec->class == 'Packager_Php_Completer' && $semiFinalBacktraceRec->function == 'autoloadJob') {
header("HTTP/1.1 200 OK");
$response = (object) [
'success' => 2,
'includedFiles' => Packager_Php_Scripts_Dependencies::CompleteIncludedFilesByTargetFile(),
'exceptionsMessages'=> self::$instance->exceptionsMessages,
'exceptionsTraces' => self::$instance->exceptionsTraces,
'content' => $content,
];
self::$instance->sendJsonResultAndExit($response);
}
}
}
public static function ExceptionHandler ($exception = NULL, $exit = TRUE) {
}
public static function ShutdownHandler () {
}
protected function shrinkPhpCode (& $code = '') {
if (!defined('T_DOC_COMMENT')) define ('T_DOC_COMMENT', -1);
if (!defined('T_ML_COMMENT')) define ('T_ML_COMMENT', -1);
$chars = '!"#$&\'()*+,-./:;<=>?@[\]^`{|}';
$chars = array_flip(preg_split('//',$chars));
$result = '';
$space = '';
$tokens = token_get_all($code);
$tokensToRemove = [
T_COMMENT => 1,
T_ML_COMMENT => 1,
T_WHITESPACE => 1,
];
if (count($this->cfg->keepPhpDocComments) === 0)
$tokensToRemove[T_DOC_COMMENT] = 1;
foreach ($tokens as & $token) {
if (is_array($token)) {
$tokenId = $token[0];
$token[3] = token_name($tokenId);
if (isset($tokensToRemove[$tokenId])) {
if ($tokenId == T_WHITESPACE) $space = ' ';
} else {
$oldPart = $token[1];
if ($tokenId == T_ECHO) $oldPart .= ' ';
if (
isset($chars[substr($result, -1)]) ||
isset($chars[$oldPart[0]])
) $space = '';
if ($tokenId == T_DOC_COMMENT)
$oldPart = $this->shrinkPhpCodeReducePhpDocComment($oldPart);
$result .= $space . $oldPart;
$space = '';
}
} else if (is_string($token)) {
$result .= $token;
}
}
return $result;
}
protected function shrinkPhpCodeReducePhpDocComment ($code) {
$keepPhpDocComments = $this->cfg->keepPhpDocComments;
$result = [];
foreach ($keepPhpDocComments as $keepPhpDocComment) {
if ($keepPhpDocComment == '@var') {
preg_match("#(@var)\s+([^\s]+)#", $code, $matchesVar);
if ($matchesVar) {
if (substr($matchesVar[2], 0, 1) == '$') {
preg_match("#(@var)\s+([\$])([^\s]+)\s+([^\s]+)#", $code, $matchesVarInline);
$result[] = $matchesVarInline
? $matchesVarInline[0]
: $matchesVar[0] ;
} else {
$result[] = $matchesVar[0];
}
}
} else if ($keepPhpDocComment == '@param') {
$index = 0;
$paramLength = mb_strlen($keepPhpDocComment);
while (TRUE) {
$paramPos = mb_strpos($code, $keepPhpDocComment, $index);
if ($paramPos === FALSE) break;
$dolarPos = mb_strpos($code, '$', $paramPos + $paramLength + 1);
if ($dolarPos === FALSE) break;
$dolarPosPlusOne = $dolarPos + 1;
$nextPos = [
mb_strpos($code, '\r', $dolarPosPlusOne),
mb_strpos($code, '\n', $dolarPosPlusOne),
mb_strpos($code, ' ', $dolarPosPlusOne),
mb_strpos($code, '\t', $dolarPosPlusOne)
];
foreach ($nextPos as $key => & $nextPosItem) if ($nextPosItem === FALSE) unset($nextPos[$key]);
if (!$nextPos) break;
$nextPosInt = min($nextPos);
$result[] = mb_substr($code, $paramPos, $nextPosInt - $paramPos);
$index = $nextPosInt + 1;
}
} else if ($keepPhpDocComment == '@return') {
preg_match("#(@return)\s+([^\s]+)#", $code, $matchesReturn);
if ($matchesReturn) $result[] = $matchesReturn[0];
} else {
preg_match("#" . $keepPhpDocComment . "\s#", $code, $matchesOther);
if ($matchesOther) $result[] = trim($matchesOther[0]);
}
}
if (!$result) return '';
return '/** '.implode(' ', $result).' */';
}
protected function completeJobAndParams () {
$jobMethod = 'mainJob';
$params = [];
if (php_sapi_name() == 'cli') {
$scriptArgsItems = array_merge($_SERVER['argv'], []);
$this->cliScriptName = array_shift($scriptArgsItems);
$params = [];
foreach ($scriptArgsItems as $scriptArgsItem) {
$firstEqualPos = strpos($scriptArgsItem, '=');
if ($firstEqualPos === FALSE) {
$params[] = $scriptArgsItem;
} else {
$paramName = substr($scriptArgsItem, 0, $firstEqualPos);
$paramValue = substr($scriptArgsItem, $firstEqualPos + 1);
$params[$paramName] = $paramValue;
}
}
} else {
$params = $_GET;
}
foreach ($params as $key => $value) {
if ($key != 'job') {
$params[$key] = base64_decode($value);
}
}
if (isset($params['job'])) {
$jobMethod = $params['job'];
unset($params['job']);
}
return [$jobMethod, $params];
}
protected function executeJobAndGetResult ($job = '', $arguments = [], $resultType = 'json') {
$jobResult = '';
if (php_sapi_name() == 'cli') {
$phpBinary = str_replace('\\', '/', PHP_BINARY);
$phpBinaryDir = dirname($phpBinary);
$phpBinaryFile = mb_substr($phpBinary, mb_strlen($phpBinaryDir) + 1);
$cwd = getcwd();
chdir($phpBinaryDir);
$command = $phpBinaryFile . ' ' . $this->cliScriptName . ' job=' . $job;
foreach ($arguments as $key => $value) {
$command .= ' ' . $key . '=' . base64_encode($value);
}
$jobResult = @exec($command, $out);
chdir($cwd);
} else {
$protocol = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
$serverPort = isset($_SERVER['SERVER_PORT']) && strval($_SERVER['SERVER_PORT']) !== '80' ? ':' . $_SERVER['SERVER_PORT'] : '';
$absoluteUrl = $protocol . $_SERVER['SERVER_NAME'] . $serverPort . $_SERVER['REQUEST_URI'];
$subProcessUrl = $absoluteUrl . '?job=' . $job;
foreach ($arguments as $key => $value) {
$subProcessUrl .= '&' . $key . '=' . base64_encode($value);
}
$cUrlResult = $this->_processGetRequest($subProcessUrl);
$jobResult = $cUrlResult->content;
}
if ($resultType == 'json') {
return self::decodeJson($jobResult);
} else {
return (object) [
'success' => TRUE,
'data' => $jobResult,
'type' => 'html',
];
}
}
protected function sendJsonResultAndExit ($jsonData) {
$jsonOut = json_encode($jsonData);
header('Content-Type: text/javascript; charset=utf-8');
header('Content-Length: ' . mb_strlen($jsonOut));
echo $jsonOut;
exit;
}
protected function completeAllFiles () {
$rdi = new \RecursiveDirectoryIterator($this->cfg->sourcesDir);
$rii = new \RecursiveIteratorIterator($rdi);
$allFiles = [];
foreach($rii as $item){
if (!$item->isDir()) {
$fullPath = str_replace('\\', '/', $item->__toString());
$relPath = substr($fullPath, strlen($this->cfg->sourcesDir));
$extension = '';
$lastDotPos = strrpos($fullPath, '.');
if ($lastDotPos !== FALSE) $extension = substr($fullPath, $lastDotPos + 1);
$extension = strtolower($extension);
$fileName = '';
$lastSlashPos = strrpos($fullPath, '/');
if ($lastSlashPos !== FALSE) $fileName = substr($fullPath, $lastSlashPos + 1);
$relPathDir = substr($relPath, 0, strlen($relPath) - strlen($fileName) - 1);
$fileItem = (object) [
'relPath' => $relPath,
'fullPath' => $fullPath,
'relPathDir' => $relPathDir,
'fileName' => $fileName,
'extension' => $extension,
'processed' => FALSE,
];
if ($this->compilationType == 'PHP') {
$fileItem->instance = $item;
$fileItem->filemtime = filemtime($fullPath);
$fileItem->filesize = filesize($fullPath);
$fileItem->utf8bomRemoved = FALSE;
$fileItem->containsNamespace = Packager_Php::NAMESPACE_NONE;
}
$allFiles[$fullPath] = $fileItem;
}
}
$this->excludeFilesByCfg($allFiles);
foreach ($allFiles as $fullPath => $fileInfo)
$allFiles[$fullPath]->content = file_get_contents($fullPath);
$this->encodeFilesToUtf8($allFiles);
if ($this->compilationType == 'PHP') {
$this->files->all = $allFiles;
} else if ($this->compilationType == 'PHAR') {
$this->files = $allFiles;
}
}
protected function excludeFilesByCfg (& $allFiles) {
$excludePatterns = $this->cfg->excludePatterns;
$includePatterns = $this->cfg->includePatterns;
foreach ($excludePatterns as $excludePattern) {
foreach ($allFiles as $fullPath => & $fileInfo) {
@preg_match($excludePattern, $fileInfo->relPath, $excludeMatches);
if ($excludeMatches) {
$unset = TRUE;
foreach ($includePatterns as & $includePattern) {
@preg_match($includePattern, $fileInfo->relPath, $includeMatches);
if ($includeMatches) {
$unset = FALSE;
break;
}
}
if ($unset) unset($allFiles[$fullPath]);
}
}
}
}
protected function encodeFilesToUtf8 (& $allFiles) {
foreach ($allFiles as $fullPath => $fileInfo) {
if (!in_array($fileInfo->extension, static::$fileTypesStoringTypes['binary'], TRUE)) {
self::_convertFilecontentToUtf8Automatically($fileInfo);
}
}
}
protected function sendResult ($title, $content, $type = '') {
if (php_sapi_name() == 'cli') {
$outputType = 'text';
if ($type == 'success') {
$title .= "\n";
for ($i = 0, $l = mb_strlen($title)-1; $i < $l; $i += 1) $title .= "=";
}
} else {
$outputType = 'html';
}
if (gettype($content) == 'string') {
$contentStr = $content;
} else {
$contentItems = [];
foreach ($content as $item) {
$contentItems[] = $this->_sendResultRenderErrorsContentItem($outputType, $item);
}
if ($outputType == 'text') {
$contentStr = implode("\n\n", $contentItems);
} else {
$contentStr = '<table><tbody><tr>'
. implode('</tr><tr>', $contentItems)
. '</tr></tbody></table>';
}
}
$responseTmpl = self::$_responseTemplates[$outputType];
$response = str_replace(
['%title', '%h1', '%content', '%style'],
[get_class($this), $title, $contentStr, self::$_htmlStyles[$type]],
$responseTmpl
);
echo $response;
exit;
}
private function _checkCommonConfiguration () {
if (!$this->cfg->sourcesDir) {
$this->sendResult(
"Source directory is an empty string.",
"Define application source directory:<br /><br />"
. "\$config['sourcesDir'] = '/path/to/development/directory';",
'error'
);
}
$this->cfg->sourcesDir = str_replace('\\', '/', realpath($this->cfg->sourcesDir));
if (!is_dir($this->cfg->sourcesDir)) {
$this->sendResult(
"Source directory not found.",
"Define application source directory:<br /><br />"
. "\$config['sourcesDir'] = '/path/to/development/directory';",
'error'
);
}
if (!$this->cfg->releaseDir) {
$this->sendResult(
"Release directory not defined or empty string.",
"Define release directory:<br /><br />"
. "\$config['releaseDir'] = '/path/to/release/directory';",
'error'
);
}
}
private function _convertFilecontentToUtf8Automatically (& $fileInfo) {
if (substr($fileInfo->content, 0, 3) == pack("CCC",0xef,0xbb,0xbf)) {
$fileInfo->content = substr($fileInfo->content, 3);
$fileInfo->utf8bomRemoved = TRUE;
} else {
if (preg_match('#[\x80-\x{1FF}\x{2000}-\x{3FFF}]#u', $fileInfo->content)) {
return;
} else {
if (preg_match('#[\x7F-\x9F\xBC]#', $fileInfo->content)) {
$fileInfo->content = iconv('WINDOWS-1250', 'UTF-8', $fileInfo->content);
} else {
$fileInfo->content = iconv('ISO-8859-2', 'UTF-8', $fileInfo->content);
}
}
}
}
private function _processGetRequest ($url) {
$ch = curl_init($url);
$timeout = 60;
$options = [
CURLOPT_HTTPHEADER => [
'Accept: text/javascript',
'Accept-Encoding: sdch, br',
'Accept-Charset: utf-8,windows-1250;q=0.7,*;q=0.3',
'Accept-Language: cs-CZ,cs;q=0.8',
'Cache-Control: no-cache',
'Cache-Control: max-age=0',
'Connection: keep-alive',
'Pragma: no-cache',
'Upgrade-Insecure-Requests: 1',
],
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_MAXREDIRS => 10,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_AUTOREFERER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => 2,
];
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$info = (object) curl_getinfo($ch);
$info->error = curl_error($ch);
$code = intval($info->http_code);
curl_close($ch);
return (object) [
'code' => $code,
'info' => $info,
'content' => $content,
];
}
private function _sendResultRenderErrorsContentItem ($outputType, $item) {
if (
!isset($item['class']) &&
!isset($item['function']) &&
!isset($item['file']) &&
!isset($item['line'])
) {
$contentItems = [];
foreach ($item as $value) {
$contentItems[] = $this->_sendResultRenderErrorsContentItem($outputType, (array) $value);
}
if ($outputType == 'text') {
return implode("\n\n", $contentItems);
} else {
return '<table><tbody><tr>' . implode('</tr><tr>', $contentItems) . '</tr></tbody></table>';
}
} else {
if ($outputType == 'text') {
return $item['class'] . '::' . $item['function'] . "();\n" . $item['file'] . ':' . $item['line'];
} else {
return '<td>' . $item['class'] . '::' . $item['function'] . '(); </td><td>' . $item['file'] . ':' . $item['line'] . '</td>';
}
}
}
private function _changeCurrentWorkingDirectoryToProjectRoot () {
$startDir = rtrim(str_replace('\\', '/', getcwd()), '/');
$projectRootDir = '';
$currentDir = $startDir;
while (TRUE) {
if (file_exists($currentDir . '/vendor/autoload.php')) {
$projectRootDir = $currentDir;
break;
} else {
$lastSlashPos = mb_strrpos($currentDir, '/');
if ($lastSlashPos === FALSE) break;
$currentDir = mb_substr($currentDir, 0, $lastSlashPos);
}
}
if ($projectRootDir && $startDir !== $projectRootDir) chdir($projectRootDir);
}
private function _setUpStrictExceptionsMode () {
$prevErrorHandler = NULL;
$errorLevels = array_fill_keys([E_ERROR,E_RECOVERABLE_ERROR,E_CORE_ERROR,E_USER_ERROR,E_WARNING,E_CORE_WARNING,E_USER_WARNING], TRUE);
$prevErrorHandler = set_error_handler(
function(
$errLevel, $errMessage, $errFile, $errLine, $errContext
) use (
& $prevErrorHandler, $errorLevels
) {
if ($errFile === '' && defined('HHVM_VERSION'))
$errFile = func_get_arg(5)[1]['file'];
if (isset($errorLevels[$errLevel]))
throw new \ErrorException($errMessage, $errLevel, $errLevel, $errFile, $errLine);
return $prevErrorHandler
? call_user_func_array($prevErrorHandler, func_get_args())
: FALSE;
}
);
}
}