diff --git a/src/Constants/PicoHttpStatus.php b/src/Constants/PicoHttpStatus.php index 3d0a3acd..b38c2092 100644 --- a/src/Constants/PicoHttpStatus.php +++ b/src/Constants/PicoHttpStatus.php @@ -1,4 +1,5 @@ of the table. - * @param array $props Array of ReflectionProperty objects representing class properties. + * @param ReflectionProperty[] $props Array of ReflectionProperty objects. * @param string $className Name of the class for reflection. * @return self Returns the current instance for method chaining. */ @@ -353,33 +350,51 @@ private function appendByProp($doc, $tbody, $props, $className) { foreach ($props as $prop) { $key = $prop->name; - $label = $key; $value = $this->get($key); - if (is_scalar($value)) { - $tr = $tbody->appendChild($doc->createElement(self::TAG_TR)); - - $reflexProp = new PicoAnnotationParser($className, $key, PicoAnnotationParser::PROPERTY); - if ($reflexProp != null) { - $parameters = $reflexProp->getParametersAsObject(); - if ($parameters->issetLabel()) { - $label = $this->label($reflexProp, $parameters, $key, $label); + // Inclusion of null values often necessary for table structure consistency + if (is_scalar($value) || $value === null) { + $label = $key; + + // Parse annotations for custom label + try { + $reflexProp = new PicoAnnotationParser($className, $key, PicoAnnotationParser::PROPERTY); + if ($reflexProp != null) { + $parameters = $reflexProp->getParametersAsObject(); + // Assuming issetLabel() or similar check exists in your annotation parser + if (method_exists($parameters, 'issetLabel') && $parameters->issetLabel()) { + $label = $this->label($reflexProp, $parameters, $key, $label); + } } + } catch (Exception $e) { + // Fallback to property name if annotation parsing fails + $label = $key; } - $td1 = $tr->appendChild($doc->createElement(self::TAG_TD)); + // Create Row + $tr = $doc->createElement(self::TAG_TR); + $tbody->appendChild($tr); + + // Column 1: Label + $td1 = $doc->createElement(self::TAG_TD); $td1->setAttribute(self::KEY_CLASS, self::TD_LABEL); - $td1->textContent = $label; + $td1->appendChild($doc->createTextNode($label)); + $tr->appendChild($td1); - $td2 = $tr->appendChild($doc->createElement(self::TAG_TD)); + // Column 2: Value + $td2 = $doc->createElement(self::TAG_TD); $td2->setAttribute(self::KEY_CLASS, self::TD_VALUE); - $td2->textContent = isset($value) ? $value : ""; + + // Safe formatting for boolean/null/strings + $displayValue = $this->formatScalarValue($value); + $td2->appendChild($doc->createTextNode($displayValue)); + $tr->appendChild($td2); } } return $this; } - /** + /** * Appends table rows based on provided values. * * This method takes an array of values and creates rows in the table, @@ -387,28 +402,55 @@ private function appendByProp($doc, $tbody, $props, $className) * * @param DOMDocument $doc The DOM document used to create elements. * @param DOMNode $tbody The DOM node representing the of the table. - * @param stdClass $values Data to append as rows. + * @param array|stdClass $values Data to append as rows. * @return self Returns the current instance for method chaining. */ private function appendByValues($doc, $tbody, $values) { + if (empty($values)) { + return $this; + } + foreach ($values as $propertyName => $value) { - if (is_scalar($value)) { - $tr = $tbody->appendChild($doc->createElement(self::TAG_TR)); - $label = $this->getLabel($propertyName); + // Check if value can be displayed as string + if (is_scalar($value) || $value === null) { + $tr = $doc->createElement(self::TAG_TR); + $tbody->appendChild($tr); - $td1 = $tr->appendChild($doc->createElement(self::TAG_TD)); + $label = $this->getLabel($propertyName); + + // Column 1: Label + $td1 = $doc->createElement(self::TAG_TD); $td1->setAttribute(self::KEY_CLASS, self::TD_LABEL); - $td1->textContent = $label; + // Use createTextNode for safer character handling + $td1->appendChild($doc->createTextNode($label)); + $tr->appendChild($td1); - $td2 = $tr->appendChild($doc->createElement(self::TAG_TD)); + // Column 2: Value + $td2 = $doc->createElement(self::TAG_TD); $td2->setAttribute(self::KEY_CLASS, self::TD_VALUE); - $td2->textContent = isset($value) ? $value : ""; + + // Format boolean or null if necessary + $displayValue = $this->formatScalarValue($value); + $td2->appendChild($doc->createTextNode($displayValue)); + $tr->appendChild($td2); } } return $this; } + /** + * Helper to ensure value is safe string for DOM + * @param mixed $value + * @return string + */ + private function formatScalarValue($value) + { + if ($value === true) return 'true'; + if ($value === false) return 'false'; + return (string)(isset($value) ? $value : ""); + } + /** * Gets the label for a specified property. * diff --git a/src/Database/PicoDatabasePersistence.php b/src/Database/PicoDatabasePersistence.php index 30c5333f..6b836477 100644 --- a/src/Database/PicoDatabasePersistence.php +++ b/src/Database/PicoDatabasePersistence.php @@ -85,6 +85,9 @@ class PicoDatabasePersistence // NOSONAR const COMMA_RETURN = ", \r\n"; const INLINE_TRIM = " \r\n\t "; const ALWAYS_TRUE = "(1=1)"; + + const IS_NULL = " is null"; + const CLAUSE_AND = " and "; /** * Database connection @@ -929,7 +932,7 @@ private function getWhere($info, $queryBuilder) $value = $queryBuilder->escapeValue($value); if(strcasecmp($value, self::KEY_NULL) == 0) { - $wheres[] = $columnName . " is null"; + $wheres[] = $columnName . self::IS_NULL; } else { @@ -940,7 +943,7 @@ private function getWhere($info, $queryBuilder) { throw new NoPrimaryKeyDefinedException("No primary key defined"); } - return implode(" and ", $wheres); + return implode(self::CLAUSE_AND, $wheres); } /** @@ -977,7 +980,7 @@ private function getWhereWithColumns($info, $queryBuilder) $escapedValue = $queryBuilder->escapeValue($value); if(strcasecmp($escapedValue, self::KEY_NULL) == 0) { - $wheres[] = $columnName . " is null"; + $wheres[] = $columnName . self::IS_NULL; $columns[$columnName] = null; } else @@ -992,7 +995,7 @@ private function getWhereWithColumns($info, $queryBuilder) } $result->columns = $columns; - $result->whereClause = implode(" and ", $wheres); + $result->whereClause = implode(self::CLAUSE_AND, $wheres); return $result; } @@ -2150,14 +2153,14 @@ private function createWhereByPrimaryKeys($queryBuilder, $primaryKeys, $property $columnValue = $propertyValues[$index]; if($columnValue === null) { - $wheres[] = $columnName . " is null"; + $wheres[] = $columnName . self::IS_NULL; } else { $wheres[] = $columnName . " = " . $queryBuilder->escapeValue($propertyValues[$index]); } } - $where = implode(" and ", $wheres); + $where = implode(self::CLAUSE_AND, $wheres); if(!$this->isValidFilter($where)) { throw new InvalidFilterException(self::MESSAGE_INVALID_FILTER); diff --git a/src/Database/PicoPageData.php b/src/Database/PicoPageData.php index 818365f1..8f3fe489 100644 --- a/src/Database/PicoPageData.php +++ b/src/Database/PicoPageData.php @@ -303,7 +303,7 @@ public function getResultAsArray() * @param mixed $data The data to convert. Can be a MagicObject, an array, an object, or a scalar value. * @return mixed The converted data as a plain PHP array, stdClass object, or scalar value. */ - protected function magicObjectToArray($data) + protected function magicObjectToArray($data) // NOSONAR { // Null or scalar if (is_null($data) || is_scalar($data)) { @@ -363,8 +363,6 @@ protected function magicObjectToArray($data) return $data; } - - /** * Get the current page number in the pagination context. * diff --git a/src/Database/PicoSpecificationFilter.php b/src/Database/PicoSpecificationFilter.php index 36890fbf..627e3be8 100644 --- a/src/Database/PicoSpecificationFilter.php +++ b/src/Database/PicoSpecificationFilter.php @@ -14,14 +14,14 @@ */ class PicoSpecificationFilter { - const DATA_TYPE_NUMBER = "number"; - const DATA_TYPE_STRING = "string"; - const DATA_TYPE_BOOLEAN = "boolean"; - const DATA_TYPE_ARRAY_NUMBER = "number[]"; - const DATA_TYPE_ARRAY_STRING = "string[]"; + const DATA_TYPE_NUMBER = "number"; + const DATA_TYPE_STRING = "string"; + const DATA_TYPE_BOOLEAN = "boolean"; + const DATA_TYPE_ARRAY_NUMBER = "number[]"; + const DATA_TYPE_ARRAY_STRING = "string[]"; const DATA_TYPE_ARRAY_BOOLEAN = "boolean[]"; - const DATA_TYPE_FULLTEXT = "fulltext"; - const DATA_TYPE_TEXT_EQUALS = "textequals"; + const DATA_TYPE_FULLTEXT = "fulltext"; + const DATA_TYPE_TEXT_EQUALS = "textequals"; /** * The name of the column this filter applies to. diff --git a/src/Database/PicoTableInfoExtended.php b/src/Database/PicoTableInfoExtended.php index 7946c03e..fd85ee47 100644 --- a/src/Database/PicoTableInfoExtended.php +++ b/src/Database/PicoTableInfoExtended.php @@ -15,9 +15,9 @@ */ class PicoTableInfoExtended extends PicoTableInfo { - const NAME = "name"; // Key for the column name + const NAME = "name"; // Key for the column name const PREV_NAME = "prevColumnName"; // Key for the previous column name - const ELEMENT = "element"; // Key for the element + const ELEMENT = "element"; // Key for the element /** * Gets an instance of PicoTableInfoExtended. diff --git a/src/Generator/PicoDatabaseDump.php b/src/Generator/PicoDatabaseDump.php index 0a660c8b..99870726 100644 --- a/src/Generator/PicoDatabaseDump.php +++ b/src/Generator/PicoDatabaseDump.php @@ -48,24 +48,18 @@ class PicoDatabaseDump // NOSONAR protected $columns = array(); /** - * Generates a SQL CREATE TABLE statement based on the provided entity schema. - * * This method detects the database type and utilizes the appropriate utility - * class to format columns, primary keys, and auto-increment constraints. - * It supports MySQL, MariaDB, PostgreSQL, SQLite, and SQL Server. + * Instantiates the appropriate database dump utility based on the database type. * - * @param array $entity The entity schema containing 'name' and 'columns' (an array of column definitions). - * @param string $databaseType The type of database (e.g., PicoDatabaseType::DATABASE_TYPE_MARIADB). - * @param bool $createIfNotExists Whether to add the "IF NOT EXISTS" clause to the CREATE statement. - * @param bool $dropIfExists Whether to prepend a commented-out "DROP TABLE IF EXISTS" statement. - * @param string $engine The storage engine to use (default is 'InnoDB', primarily for MySQL/MariaDB). - * @param string $charset The character set for the table (default is 'utf8mb4'). - * * @return string The generated SQL DDL statement or an empty string if the database type is unsupported. + * This factory method maps specific database engines to their respective + * utility classes (MySQL, PostgreSQL, SQLite, or SQL Server) to handle + * database-specific dumping operations. + * + * @param string $databaseType The type of database (e.g., MySQL, PostgreSQL, SQLite). + * @return PicoDatabaseUtilBase|string Returns an instance of the database utility tool + * or an empty string if the database type is not supported. */ - public function dumpStructureFromSchema($entity, $databaseType, $createIfNotExists = false, $dropIfExists = false, $engine = 'InnoDB', $charset = 'utf8mb4') + private function getDatabaseDumpTool($databaseType) { - $tableName = $entity['name']; - - // 1. Initialize Tool based on Database Type switch ($databaseType) { case PicoDatabaseType::DATABASE_TYPE_MARIADB: case PicoDatabaseType::DATABASE_TYPE_MYSQL: @@ -84,6 +78,29 @@ public function dumpStructureFromSchema($entity, $databaseType, $createIfNotExis default: return ""; } + return $tool; + } + + /** + * Generates a SQL CREATE TABLE statement based on the provided entity schema. + * * This method detects the database type and utilizes the appropriate utility + * class to format columns, primary keys, and auto-increment constraints. + * It supports MySQL, MariaDB, PostgreSQL, SQLite, and SQL Server. + * + * @param array $entity The entity schema containing 'name' and 'columns' (an array of column definitions). + * @param string $databaseType The type of database (e.g., PicoDatabaseType::DATABASE_TYPE_MARIADB). + * @param bool $createIfNotExists Whether to add the "IF NOT EXISTS" clause to the CREATE statement. + * @param bool $dropIfExists Whether to prepend a commented-out "DROP TABLE IF EXISTS" statement. + * @param string $engine The storage engine to use (default is 'InnoDB', primarily for MySQL/MariaDB). + * @param string $charset The character set for the table (default is 'utf8mb4'). + * @return string The generated SQL DDL statement or an empty string if the database type is unsupported. + */ + public function dumpStructureFromSchema($entity, $databaseType, $createIfNotExists = false, $dropIfExists = false, $engine = 'InnoDB', $charset = 'utf8mb4') + { + $tableName = $entity['name']; + + // 1. Initialize Tool based on Database Type + $tool = $this->getDatabaseDumpTool($databaseType); $columns = array(); $primaryKeys = array(); @@ -154,15 +171,11 @@ public function dumpDataFromSchema($entity, $databaseType, $batchSize = 100) { // Check if the target database is PostgreSQL $isPgSql = $databaseType == PicoDatabaseType::DATABASE_TYPE_PGSQL || $databaseType == PicoDatabaseType::DATABASE_TYPE_POSTGRESQL; - $columnInfo = array(); + $tableName = $entity['name']; // 1. Prepare Column Information for type-casting - if (isset($entity['columns']) && is_array($entity['columns'])) { - foreach ($entity['columns'] as $column) { - $columnInfo[$column['name']] = $this->getColumnInfo($column); - } - } + $columnInfo = $this->prepareColumnInfo($entity); $validColumnNames = array_keys($columnInfo); @@ -203,12 +216,34 @@ public function dumpDataFromSchema($entity, $databaseType, $batchSize = 100) . implode(",\r\n", $rows) . ";\r\n\r\n"; } - } return $allSql; } + /** + * Prepares and normalizes column metadata from the entity schema. + * + * This method iterates through the column definitions of an entity and + * transforms them into a structured associative array of column information, + * indexed by the column names. + * + * @param array $entity The entity schema containing the 'columns' definition. + * @return array An associative array where keys are column names + * and values are column metadata objects. + */ + private function prepareColumnInfo($entity) + { + $columnInfo = array(); + if (isset($entity['columns']) && is_array($entity['columns'])) { + foreach ($entity['columns'] as $column) { + // Assuming getColumnInfo returns an object/stdClass based on previous code + $columnInfo[$column['name']] = $this->getColumnInfo($column); + } + } + return $columnInfo; + } + /** * Formats raw data values based on column metadata and database requirements. * diff --git a/src/MagicDto.php b/src/MagicDto.php index 72e5271d..0b1fea1f 100644 --- a/src/MagicDto.php +++ b/src/MagicDto.php @@ -395,10 +395,13 @@ private function isSelfInstance($objectTest) */ private function isMagicObjectInstance($objectTest) { - return isset($objectTest) && ($objectTest instanceof MagicObject || + return isset($objectTest) && + ( + $objectTest instanceof MagicObject || $objectTest instanceof SetterGetter || $objectTest instanceof SecretObject || - $objectTest instanceof PicoGenericObject); + $objectTest instanceof PicoGenericObject + ); } /** diff --git a/src/MagicObject.php b/src/MagicObject.php index ab07245e..8399344e 100644 --- a/src/MagicObject.php +++ b/src/MagicObject.php @@ -11,7 +11,6 @@ use MagicObject\Database\PicoDatabasePersistenceExtended; use MagicObject\Database\PicoDatabaseQueryBuilder; use MagicObject\Database\PicoDatabaseQueryTemplate; -use MagicObject\Database\PicoDatabaseType; use MagicObject\Database\PicoPageable; use MagicObject\Database\PicoPageData; use MagicObject\Database\PicoSort; diff --git a/src/Response/PicoResponse.php b/src/Response/PicoResponse.php index 8e35a251..673824d1 100644 --- a/src/Response/PicoResponse.php +++ b/src/Response/PicoResponse.php @@ -140,39 +140,42 @@ public static function sendHeaders($headers) */ public static function sendBody($body, $async = false) { + $content = ($body !== null) ? $body : ""; + $contentLength = strlen($content); + if ($async) { + // Allow script to continue running after connection is closed if (function_exists('ignore_user_abort')) { ignore_user_abort(true); } - ob_start(); // Mulai output buffering + + // Start buffering to control when data is sent + ob_start(); } - header("Connection: close"); - // Jika body tidak null, kirimkan - if ($body !== null && $async) { - echo $body; // Tampilkan body - } + // 1. Set Headers (Must be sent before any body content) + header("Connection: close"); + header("Content-Length: " . $contentLength); - // Mengatur header koneksi - + // 2. Output the content + echo $content; - // Jika dalam mode asinkron, lakukan flush if ($async) { - ob_end_flush(); // Selesaikan buffer - header("Content-Length: " . strlen($body)); // Tentukan panjang konten - flush(); // Kirim output ke klien + // 3. Flush all buffers to the client + $size = ob_get_length(); + header("Content-Length: " . $size); // Optional: Re-confirm size + + ob_end_flush(); + flush(); + + // 4. Specifically for FastCGI (Nginx/PHP-FPM) + // This closes the connection to the user but keeps the script alive if (function_exists('fastcgi_finish_request')) { - fastcgi_finish_request(); // Selesaikan permintaan FastCGI - } - } else { - // Jika tidak asinkron, atur Content-Length - if ($body !== null) { - header("Content-Length: " . strlen($body)); // Tentukan panjang konten - echo $body; // Tampilkan body + fastcgi_finish_request(); } } } - + /** * Get default content type based on the provided content type. * diff --git a/src/Util/Database/PicoDatabaseUtilBase.php b/src/Util/Database/PicoDatabaseUtilBase.php index 92004c1a..651821b9 100644 --- a/src/Util/Database/PicoDatabaseUtilBase.php +++ b/src/Util/Database/PicoDatabaseUtilBase.php @@ -439,7 +439,6 @@ public function importDataTable( return false; } catch (Exception $e) { - error_log($e->getMessage()); return false; } } @@ -541,7 +540,6 @@ public function importData($config, $callbackFunction, $tableName = null, $limit } catch(Exception $e) { - error_log($e->getMessage()); return false; } return true; diff --git a/src/Util/Database/PicoDatabaseUtilMySql.php b/src/Util/Database/PicoDatabaseUtilMySql.php index a8e0d4c0..f02dc5d9 100644 --- a/src/Util/Database/PicoDatabaseUtilMySql.php +++ b/src/Util/Database/PicoDatabaseUtilMySql.php @@ -304,7 +304,7 @@ public function autoConfigureImportData($config) } catch(Exception $e) { - error_log($e->getMessage()); + // Do nothing } return $config; } diff --git a/src/Util/Database/PicoDatabaseUtilSqlServer.php b/src/Util/Database/PicoDatabaseUtilSqlServer.php index ed9f927c..09ce3ddf 100644 --- a/src/Util/Database/PicoDatabaseUtilSqlServer.php +++ b/src/Util/Database/PicoDatabaseUtilSqlServer.php @@ -336,7 +336,7 @@ public function autoConfigureImportData($config) } $config->setTable($tables); } catch (Exception $e) { - error_log($e->getMessage()); + // Do nothing } return $config; } diff --git a/src/Util/Database/PicoDatabaseUtilSqlite.php b/src/Util/Database/PicoDatabaseUtilSqlite.php index bb925e60..3c775924 100644 --- a/src/Util/Database/PicoDatabaseUtilSqlite.php +++ b/src/Util/Database/PicoDatabaseUtilSqlite.php @@ -485,7 +485,7 @@ public function sqliteToMysqlType($type) // NOSONAR * @param array $autoIncrementKeys List of keys designated as auto-incrementing. * @param array $primaryKeys List of all primary key columns to determine if a * composite key (multiple PKs) exists. - * * @return string The formatted SQL column definition string. + * @return string The formatted SQL column definition string. */ public function createColumn($column, $autoIncrementKeys, $primaryKeys) { @@ -669,7 +669,7 @@ public function autoConfigureImportData($config) } catch(Exception $e) { - error_log($e->getMessage()); + // Do nothing } return $config; } diff --git a/src/Util/Image/ImageResize.php b/src/Util/Image/ImageResize.php index 298d235b..319f9ca5 100644 --- a/src/Util/Image/ImageResize.php +++ b/src/Util/Image/ImageResize.php @@ -27,8 +27,6 @@ public function resizeImage($sourcePath, $destPath, $maxWidth, $maxHeight) { $resizedImage = imagecreatetruecolor($newWidth, $newHeight); imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); imagejpeg($resizedImage, $destPath); - imagedestroy($image); - imagedestroy($resizedImage); } /** @@ -62,9 +60,6 @@ public function resizeCropCenter($sourcePath, $destPath, $targetWidth, $targetHe imagecopy($finalImage, $resizedImage, $x, $y, 0, 0, $newWidth, $newHeight); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($resizedImage); - imagedestroy($finalImage); } /** @@ -98,8 +93,6 @@ public function resizePaddingCenter($sourcePath, $destPath, $targetWidth, $targe imagecopyresampled($finalImage, $image, $x, $y, 0, 0, $newWidth, $newHeight, $width, $height); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($finalImage); } /** @@ -131,9 +124,6 @@ public function resizeCropTopLeft($sourcePath, $destPath, $targetWidth, $targetH imagecopy($finalImage, $resizedImage, 0, 0, 0, 0, $targetWidth, $targetHeight); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($resizedImage); - imagedestroy($finalImage); } /** @@ -167,8 +157,6 @@ public function resizePaddingTopRight($sourcePath, $destPath, $targetWidth, $tar imagecopyresampled($finalImage, $image, $x, $y, 0, 0, $newWidth, $newHeight, $width, $height); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($finalImage); } /** @@ -200,9 +188,6 @@ public function resizeCropTopRight($sourcePath, $destPath, $targetWidth, $target imagecopy($finalImage, $resizedImage, $targetWidth - $newWidth, 0, 0, 0, $targetWidth, $targetHeight); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($resizedImage); - imagedestroy($finalImage); } /** @@ -234,9 +219,6 @@ public function resizeCropBottomLeft($sourcePath, $destPath, $targetWidth, $targ imagecopy($finalImage, $resizedImage, 0, $targetHeight - $newHeight, 0, 0, $targetWidth, $targetHeight); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($resizedImage); - imagedestroy($finalImage); } /** @@ -268,9 +250,6 @@ public function resizeCropBottomRight($sourcePath, $destPath, $targetWidth, $tar imagecopy($finalImage, $resizedImage, $targetWidth - $newWidth, $targetHeight - $newHeight, 0, 0, $targetWidth, $targetHeight); imagejpeg($finalImage, $destPath); - imagedestroy($image); - imagedestroy($resizedImage); - imagedestroy($finalImage); } /** @@ -291,8 +270,6 @@ public function flipVertical($sourcePath, $destPath) { } imagejpeg($flippedImage, $destPath); - imagedestroy($image); - imagedestroy($flippedImage); } /** @@ -313,8 +290,6 @@ public function flipHorizontal($sourcePath, $destPath) { } imagejpeg($flippedImage, $destPath); - imagedestroy($image); - imagedestroy($flippedImage); } /** @@ -328,8 +303,6 @@ public function rotate90($sourcePath, $destPath) { $image = imagecreatefromjpeg($sourcePath); $rotatedImage = imagerotate($image, -90, 0); imagejpeg($rotatedImage, $destPath); - imagedestroy($image); - imagedestroy($rotatedImage); } /** @@ -343,8 +316,6 @@ public function rotate180($sourcePath, $destPath) { $image = imagecreatefromjpeg($sourcePath); $rotatedImage = imagerotate($image, 180, 0); imagejpeg($rotatedImage, $destPath); - imagedestroy($image); - imagedestroy($rotatedImage); } /** @@ -358,8 +329,6 @@ public function rotate270($sourcePath, $destPath) { $image = imagecreatefromjpeg($sourcePath); $rotatedImage = imagerotate($image, 90, 0); imagejpeg($rotatedImage, $destPath); - imagedestroy($image); - imagedestroy($rotatedImage); } /** @@ -384,7 +353,6 @@ public function addWatermark($sourcePath, $watermarkPath, $outputPath, $opacity // Load the watermark image $watermarkImage = imagecreatefrompng($watermarkPath); if (!$watermarkImage) { - imagedestroy($sourceImage); // Free memory for the source image return false; // Return false if the watermark cannot be loaded } @@ -438,10 +406,6 @@ public function addWatermark($sourcePath, $watermarkPath, $outputPath, $opacity // Save the resulting image imagejpeg($sourceImage, $outputPath); - // Free memory for the images - imagedestroy($sourceImage); - imagedestroy($watermarkImage); - return true; // Return true on successful watermarking } } diff --git a/src/Util/Image/ImageUtil.php b/src/Util/Image/ImageUtil.php index 47086142..ad8e8c9c 100644 --- a/src/Util/Image/ImageUtil.php +++ b/src/Util/Image/ImageUtil.php @@ -290,7 +290,6 @@ public function flip($type) imagecopy($imgdest, $rowBuffer, 0, $y, 0, 0, $width, 1); } - imagedestroy($rowBuffer); break; } @@ -344,7 +343,7 @@ public function resize($newWidth = null, $newHeight = null) * @return ImageUtil * @throws ImageUtilException If an error occurs during resizing. */ - public function resizeSquare($newSize, ImageColor $color = null) + public function resizeSquare($newSize, $color = null) { return $this->resizeAspectRatio($newSize, $newSize, $color); } @@ -358,7 +357,7 @@ public function resizeSquare($newSize, ImageColor $color = null) * @return self Returns the current instance for method chaining. * @throws ImageUtilException If an error occurs during resizing. */ - public function resizeAspectRatio($newX, $newY, ImageColor $color = null) + public function resizeAspectRatio($newX, $newY, $color = null) { if (empty($color)) { $color = new ImageColorAlpha(255, 255, 255, 127); @@ -606,7 +605,7 @@ public function restore() * @param GdImage|null $image The image resource to modify. If null, uses the current image. * @return $this|GdImage The modified image or the current instance. */ - public function makeTransparent(ImageColor $color = null, $image = null) + public function makeTransparent($color = null, $image = null) { if (empty($color)) { $color = new ImageColor(255, 255, 255); @@ -655,8 +654,6 @@ public function makeTransparent(ImageColor $color = null, $image = null) public function __destruct() { if (!is_null($this->image)) { - imagedestroy($this->image); - imagedestroy($this->orgImage); unset($this->image); unset($this->orgImage); }