From 8b9538f1180869faf34b9b22a515cd9461fda36a Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Thu, 20 Mar 2014 18:06:35 +0200 Subject: [PATCH 1/3] fixed monolog errors --- api/v1/index.php | 2 - application/Espo/Core/Loaders/Log.php | 23 ++-- application/Espo/Core/Utils/Log.php | 29 +---- .../Monolog/Handler/RotatingFileHandler.php | 117 ++++++++++++++++++ .../Log/Monolog/Handler/StreamHandler.php | 66 ++++++++++ .../Espo/Core/Utils/Log/Monolog/Logger.php | 49 ++++++++ 6 files changed, 250 insertions(+), 36 deletions(-) create mode 100644 application/Espo/Core/Utils/Log/Monolog/Handler/RotatingFileHandler.php create mode 100644 application/Espo/Core/Utils/Log/Monolog/Handler/StreamHandler.php create mode 100644 application/Espo/Core/Utils/Log/Monolog/Logger.php diff --git a/api/v1/index.php b/api/v1/index.php index fa61af0342..d231e48138 100644 --- a/api/v1/index.php +++ b/api/v1/index.php @@ -1,7 +1,5 @@ getContainer()->get('config'); + $logConfig = $this->getContainer()->get('config')->get('logger'); - $logConfig = $config->get('logger'); - - $log = new Utils\Log('Espo'); - $levelCode = $log->getLevelCode($logConfig['level']); + $log = new Utils\Log('Espo'); + + $levelCode = $log->getLevelCode($logConfig['level']); if ($logConfig['isRotate']) { $handler = new Handler\RotatingFileHandler($logConfig['path'], $logConfig['maxRotateFiles'], $levelCode); @@ -54,7 +53,11 @@ class Log $handler = new Handler\StreamHandler($logConfig['path'], $levelCode); } $log->pushHandler($handler); - \Monolog\ErrorHandler::register($log); + + $errorHandler = new \Monolog\ErrorHandler($log); + $errorHandler->registerExceptionHandler(null, false); + $errorHandler->registerErrorHandler(array(), false); + $errorHandler->registerFatalHandler(); return $log; } diff --git a/application/Espo/Core/Utils/Log.php b/application/Espo/Core/Utils/Log.php index 524d4874f1..157d9a756f 100644 --- a/application/Espo/Core/Utils/Log.php +++ b/application/Espo/Core/Utils/Log.php @@ -1,4 +1,4 @@ -getLevels(); - - if (isset($levels[$levelName])) { - return $levels[$levelName]; - } - - return $levels[$this->defaultLevelName]; - } - } diff --git a/application/Espo/Core/Utils/Log/Monolog/Handler/RotatingFileHandler.php b/application/Espo/Core/Utils/Log/Monolog/Handler/RotatingFileHandler.php new file mode 100644 index 0000000000..332790bfa2 --- /dev/null +++ b/application/Espo/Core/Utils/Log/Monolog/Handler/RotatingFileHandler.php @@ -0,0 +1,117 @@ +filename = $filename; + $this->maxFiles = (int) $maxFiles; + + parent::__construct($this->getTimedFilename(), $level, $bubble); + + $this->rotate(); + } + + public function setFilenameFormat($filenameFormat, $dateFormat) + { + $this->filenameFormat = $filenameFormat; + $this->dateFormat = $dateFormat; + } + + protected function rotate() + { + if (0 === $this->maxFiles) { + return; //unlimited number of files for 0 + } + + $filePattern = $this->getFilePattern(); + $dirPath = $this->getFileManager()->getDirName($this->filename); + $logFiles = $this->getFileManager()->getFileList($dirPath, false, $filePattern, 'file'); + + if (!empty($logFiles) && count($logFiles) > $this->maxFiles) { + + usort($logFiles, function($a, $b) { + return strcmp($b, $a); + }); + + $logFilesToBeRemoved = array_slice($logFiles, $this->maxFiles); + + $this->getFileManager()->removeFiles($logFilesToBeRemoved, $dirPath); + } + } + + protected function getTimedFilename() + { + $fileInfo = pathinfo($this->filename); + $timedFilename = str_replace( + array('{filename}', '{date}'), + array($fileInfo['filename'], date($this->dateFormat)), + $fileInfo['dirname'] . '/' . $this->filenameFormat + ); + + if (!empty($fileInfo['extension'])) { + $timedFilename .= '.'.$fileInfo['extension']; + } + + return $timedFilename; + } + + protected function getFilePattern() + { + $fileInfo = pathinfo($this->filename); + $glob = str_replace( + array('{filename}', '{date}'), + array($fileInfo['filename'], '.*'), + $this->filenameFormat + ); + + if (!empty($fileInfo['extension'])) { + $glob .= '\.'.$fileInfo['extension']; + } + + $glob = '^'.$glob.'$'; + + return $glob; + } +} \ No newline at end of file diff --git a/application/Espo/Core/Utils/Log/Monolog/Handler/StreamHandler.php b/application/Espo/Core/Utils/Log/Monolog/Handler/StreamHandler.php new file mode 100644 index 0000000000..d543a83fe8 --- /dev/null +++ b/application/Espo/Core/Utils/Log/Monolog/Handler/StreamHandler.php @@ -0,0 +1,66 @@ +fileManager = new \Espo\Core\Utils\File\Manager(); + } + + protected function getFileManager() + { + return $this->fileManager; + } + + + protected function write(array $record) + { + if (!$this->url) { + throw new \LogicException('Missing logger path, the stream can not be opened. Please check logger options in the data/config.php.'); + } + + $this->errorMessage = null; + + set_error_handler(array($this, 'customErrorHandler')); + $this->getFileManager()->appendContents($this->url, (string) $record['formatted']); + restore_error_handler(); + + if (isset($this->errorMessage)) { + throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url)); + } + } + + private function customErrorHandler($code, $msg) + { + $this->errorMessage = $msg; + } + +} \ No newline at end of file diff --git a/application/Espo/Core/Utils/Log/Monolog/Logger.php b/application/Espo/Core/Utils/Log/Monolog/Logger.php new file mode 100644 index 0000000000..d11badc768 --- /dev/null +++ b/application/Espo/Core/Utils/Log/Monolog/Logger.php @@ -0,0 +1,49 @@ +getLevels(); + + if (isset($levels[$levelName])) { + return $levels[$levelName]; + } + + return $levels[$this->defaultLevelName]; + } + + +} \ No newline at end of file From d547d691fe9086d908e8e37bbd91cf972bfeedc0 Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Fri, 21 Mar 2014 12:46:23 +0200 Subject: [PATCH 2/3] renamed notnull to notNull in ORM --- .../Core/Utils/Database/Orm/Converter.php | 34 +++++++++---------- .../Utils/Database/Orm/Fields/LinkParent.php | 8 ++--- .../Core/Utils/Database/Schema/Converter.php | 30 ++++++++-------- .../Espo/Resources/metadata/fields/date.json | 2 +- .../Resources/metadata/fields/datetime.json | 2 +- .../Espo/Resources/metadata/fields/float.json | 2 +- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/application/Espo/Core/Utils/Database/Orm/Converter.php b/application/Espo/Core/Utils/Database/Orm/Converter.php index 191d19e510..c160a3cb24 100644 --- a/application/Espo/Core/Utils/Database/Orm/Converter.php +++ b/application/Espo/Core/Utils/Database/Orm/Converter.php @@ -1,4 +1,4 @@ - ORM */ protected $fieldAccordances = array( 'type' => 'type', 'dbType' => 'dbType', 'maxLength' => 'len', 'len' => 'len', - 'notnull' => 'notnull', + 'notNull' => 'notNull', 'autoincrement' => 'autoincrement', 'notStorable' => 'notStorable', 'link' => 'relation', @@ -60,7 +60,7 @@ class Converter 'unique' => 'unique', 'index' => 'index', /*'conditions' => 'conditions', - 'additionalColumns' => 'additionalColumns', */ + 'additionalColumns' => 'additionalColumns', */ 'default' => array( 'condition' => '^javascript:', 'conditionEquals' => false, @@ -199,7 +199,7 @@ class Converter case 'foreignId': $fieldParams = array_merge($fieldParams, $this->idParams); - $fieldParams['notnull'] = false; + $fieldParams['notNull'] = false; break; case 'foreignType': @@ -304,12 +304,12 @@ class Converter $fieldParams = Util::merge($fieldParams, $fieldTypeMeta['database']); } - //if defined 'notnull => false' and 'required => true', then remove 'notnull' - if (isset($fieldParams['notnull']) && !$fieldParams['notnull'] && isset($fieldParams['required']) && $fieldParams['required']) { - unset($fieldParams['notnull']); - } //END + //if defined 'notNull => false' and 'required => true', then remove 'notNull' + if (isset($fieldParams['notNull']) && !$fieldParams['notNull'] && isset($fieldParams['required']) && $fieldParams['required']) { + unset($fieldParams['notNull']); + } //END + - $fieldDefs = $this->getInitValues($fieldParams); //check if field need to be saved in database @@ -448,23 +448,23 @@ class Converter protected function getInitValues(array $fieldParams) { $values = array(); - foreach($this->fieldAccordances as $espoType => $doctrineType) { + foreach($this->fieldAccordances as $espoType => $ormType) { if (isset($fieldParams[$espoType])) { - if (is_array($doctrineType)) { + if (is_array($ormType)) { $conditionRes = false; if (!is_array($fieldParams[$espoType])) { - $conditionRes = preg_match('/'.$doctrineType['condition'].'/i', $fieldParams[$espoType]); + $conditionRes = preg_match('/'.$ormType['condition'].'/i', $fieldParams[$espoType]); } - if (!$conditionRes || ($conditionRes && $conditionRes === $doctrineType['conditionEquals']) ) { + if (!$conditionRes || ($conditionRes && $conditionRes === $ormType['conditionEquals']) ) { $value = is_array($fieldParams[$espoType]) ? json_encode($fieldParams[$espoType]) : $fieldParams[$espoType]; - $values = Util::merge( $values, Util::replaceInArray('{0}', $value, $doctrineType['value']) ); + $values = Util::merge( $values, Util::replaceInArray('{0}', $value, $ormType['value']) ); } } else { - $values[$doctrineType] = $fieldParams[$espoType]; + $values[$ormType] = $fieldParams[$espoType]; } } diff --git a/application/Espo/Core/Utils/Database/Orm/Fields/LinkParent.php b/application/Espo/Core/Utils/Database/Orm/Fields/LinkParent.php index 2809b6e9be..6e7b779056 100644 --- a/application/Espo/Core/Utils/Database/Orm/Fields/LinkParent.php +++ b/application/Espo/Core/Utils/Database/Orm/Fields/LinkParent.php @@ -1,4 +1,4 @@ - array( 'type' => 'foreignType', - 'notnull' => false, - 'index' => $field['name'], + 'notNull' => false, + 'index' => $field['name'], ), $field['name'].'Name' => array( 'type' => 'varchar', diff --git a/application/Espo/Core/Utils/Database/Schema/Converter.php b/application/Espo/Core/Utils/Database/Schema/Converter.php index 591de5c1e8..33ebed3f92 100644 --- a/application/Espo/Core/Utils/Database/Schema/Converter.php +++ b/application/Espo/Core/Utils/Database/Schema/Converter.php @@ -1,4 +1,4 @@ - doctrine protected $allowedDbFieldParams = array( 'len' => 'length', 'default' => 'default', - 'notnull' => 'notnull', + 'notNull' => 'notnull', 'autoincrement' => 'autoincrement', 'unique' => 'unique', ); @@ -87,14 +87,14 @@ class Converter $GLOBALS['log']->debug('Schema\Converter - Start: building schema'); //check if exist files in "Tables" directory and merge with ormMetadata - $ormMeta = Util::merge($ormMeta, $this->getCustomTables()); + $ormMeta = Util::merge($ormMeta, $this->getCustomTables()); //unset some keys in orm if (isset($ormMeta['unset'])) { $ormMeta = Util::unsetInArray($ormMeta, $ormMeta['unset']); unset($ormMeta['unset']); } //END: unset some keys in orm - + $schema = $this->getSchema(); @@ -115,7 +115,7 @@ class Converter switch ($fieldParams['type']) { case 'id': $primaryColumns[] = Util::toUnderScore($fieldName); - break; + break; } $fieldType = isset($fieldParams['dbType']) ? $fieldParams['dbType'] : $fieldParams['type']; @@ -130,13 +130,13 @@ class Converter } //add unique - if ($fieldParams['type']!= 'id' && isset($fieldParams['unique'])) { + if ($fieldParams['type']!= 'id' && isset($fieldParams['unique'])) { $uniqueColumns = $this->getKeyList($columnName, $fieldParams['unique'], $uniqueColumns); } //END: add unique //add index. It can be defined in entityDefs as "index" if (isset($fieldParams['index'])) { - $indexList = $this->getKeyList($columnName, $fieldParams['index'], $indexList); + $indexList = $this->getKeyList($columnName, $fieldParams['index'], $indexList); } //END: add index } @@ -150,8 +150,8 @@ class Converter if (!empty($uniqueColumns)) { foreach($uniqueColumns as $uniqueItem) { $tables[$entityName]->addUniqueIndex($uniqueItem); - } - } + } + } } //check and create columns/tables for relations @@ -171,7 +171,7 @@ class Converter if (!isset($tables[$tableName])) { //no needs to create the table if it already exists $tables[$tableName] = $this->prepareManyMany($entityName, $relationParams, $tables); } - break; + break; case 'belongsTo': $foreignEntity = $relationParams['entity']; @@ -288,8 +288,8 @@ class Converter /** * Get key list (index, unique). Ex. index => true OR index => 'somename' * @param string $columnName Column name (underscore field name) - * @param bool | string $keyValue - * @return array + * @param bool | string $keyValue + * @return array */ protected function getKeyList($columnName, $keyValue, array $keyList) { @@ -314,7 +314,7 @@ class Converter foreach($fileList as $fileName) { $fileData = $this->getFileManager()->getContents( array($this->customTablePath, $fileName) ); - if (is_array($fileData)) { + if (is_array($fileData)) { $customTables = Util::merge($customTables, $fileData); } } diff --git a/application/Espo/Resources/metadata/fields/date.json b/application/Espo/Resources/metadata/fields/date.json index bd314941d4..15bbe7e9f1 100644 --- a/application/Espo/Resources/metadata/fields/date.json +++ b/application/Espo/Resources/metadata/fields/date.json @@ -23,6 +23,6 @@ "advanced":true }, "database":{ - "notnull":false + "notNull":false } } diff --git a/application/Espo/Resources/metadata/fields/datetime.json b/application/Espo/Resources/metadata/fields/datetime.json index 2089e6d64a..a190ecee56 100644 --- a/application/Espo/Resources/metadata/fields/datetime.json +++ b/application/Espo/Resources/metadata/fields/datetime.json @@ -23,6 +23,6 @@ "advanced":false }, "database":{ - "notnull":false + "notNull":false } } diff --git a/application/Espo/Resources/metadata/fields/float.json b/application/Espo/Resources/metadata/fields/float.json index eab97a369c..3f6ac595e3 100644 --- a/application/Espo/Resources/metadata/fields/float.json +++ b/application/Espo/Resources/metadata/fields/float.json @@ -23,6 +23,6 @@ "advanced":true }, "database":{ - "notnull":false + "notNull":false } } From 16ea1a83b7040520640705d89941c9857a401f5d Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Fri, 21 Mar 2014 13:05:38 +0200 Subject: [PATCH 3/3] changed LIKE, = for 'person name' --- .../Utils/Database/Orm/Fields/PersonName.php | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/application/Espo/Core/Utils/Database/Orm/Fields/PersonName.php b/application/Espo/Core/Utils/Database/Orm/Fields/PersonName.php index f81fa8af2f..db5c8135c9 100644 --- a/application/Espo/Core/Utils/Database/Orm/Fields/PersonName.php +++ b/application/Espo/Core/Utils/Database/Orm/Fields/PersonName.php @@ -1,4 +1,4 @@ -getForeignField($field['name'], $entity['name']); + $foreignField = $this->getForeignField($field['name'], $entity['name']); $tableName = Util::toUnderScore($entity['name']); $fullList = array(); //contains empty string (" ") like delimiter + $fullListReverse = array(); //reverse of $fullList $fieldList = array(); //doesn't contain empty string (" ") like delimiter $like = array(); + $equal = array(); + foreach($foreignField as $fieldName) { - $fieldNameTrimmed = trim($fieldName); + $fieldNameTrimmed = trim($fieldName); if (!empty($fieldNameTrimmed)) { $columnName = $tableName.'.'.Util::toUnderScore($fieldNameTrimmed); - $fullList[] = $fieldList[] = $columnName; + $fullList[] = $fieldList[] = $columnName; $like[] = $columnName." LIKE '{text}'"; + $equal[] = $columnName." = '{text}'"; } else { - $fullList[] = "'".$fieldName."'"; + $fullList[] = "'".$fieldName."'"; } } - return array( + $fullListReverse = array_reverse($fullList); + + return array( $entity['name'] => array ( - 'fields' => array( - $field['name'] => array( - 'type' => 'varchar', + 'fields' => array( + $field['name'] => array( + 'type' => 'varchar', 'select' => "TRIM(CONCAT(".implode(", ", $fullList)."))", - 'where' => array( - 'LIKE' => "(".implode(" OR ", $like)." OR CONCAT(".implode(", ", $fullList).") LIKE '{text}')", - ), - 'orderBy' => implode(", ", array_map(function ($item) {return $item . ' {direction}';}, $fieldList)), + 'where' => array( + 'LIKE' => "(".implode(" OR ", $like)." OR CONCAT(".implode(", ", $fullList).") LIKE '{text}' OR CONCAT(".implode(", ", $fullListReverse).") LIKE '{text}')", + '=' => "(".implode(" OR ", $equal)." OR CONCAT(".implode(", ", $fullList).") = '{text}' OR CONCAT(".implode(", ", $fullListReverse).") = '{text}')", + ), + 'orderBy' => implode(", ", array_map(function ($item) {return $item . ' {direction}';}, $fieldList)), ), ), ),