made some refactoring
This commit is contained in:
parent
f76eb08fe0
commit
38676bc9fd
9
.env
Normal file
9
.env
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
APP_NAME=Project
|
||||||
|
APP_ENV=local
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=laraspace
|
||||||
|
DB_USERNAME=laraspace
|
||||||
|
DB_PASSWORD="👨🍳🥚🧂🥛=🍽️💪"
|
@ -2,8 +2,9 @@
|
|||||||
<module type="WEB_MODULE" version="4">
|
<module type="WEB_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/evenement/evenement" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/evenement/evenement" />
|
||||||
@ -37,16 +38,21 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/carbonphp/carbon-doctrine-types" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpfui/orm" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpfui/translation" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/clock" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||||
@ -60,6 +66,10 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/staabm/side-effects-detector" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/staabm/side-effects-detector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/clock" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php83" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
@ -95,6 +95,15 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpfui/orm" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/phpfui/translation" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/psr/clock" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/clock" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php83" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/carbonphp/carbon-doctrine-types" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.3" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.3" />
|
||||||
|
@ -4,11 +4,11 @@ declare(strict_types = 1);
|
|||||||
|
|
||||||
use PhpCsFixer\{Config, Finder, Runner\Parallel\ParallelConfigFactory};
|
use PhpCsFixer\{Config, Finder, Runner\Parallel\ParallelConfigFactory};
|
||||||
|
|
||||||
$finder = (new Finder())->in([
|
$finder = (new Finder)->in([
|
||||||
__DIR__ . '/src',
|
__DIR__ . '/src',
|
||||||
])->exclude(['vendor'])->name('*.php')->ignoreDotFiles(true);
|
])->exclude(['vendor'])->name('*.php')->ignoreDotFiles(true);
|
||||||
|
|
||||||
return (new Config())->setRules([
|
return (new Config)->setRules([
|
||||||
'@PSR12' => true,
|
'@PSR12' => true,
|
||||||
'declare_equal_normalize' => [
|
'declare_equal_normalize' => [
|
||||||
'space' => 'single',
|
'space' => 'single',
|
||||||
@ -21,6 +21,9 @@ return (new Config())->setRules([
|
|||||||
'=>' => null,
|
'=>' => null,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'new_with_parentheses' => [
|
||||||
|
'named_class' => false,
|
||||||
|
]
|
||||||
])->setParallelConfig(ParallelConfigFactory::detect())->setUsingCache(true)->setRiskyAllowed(true)->setFinder(
|
])->setParallelConfig(ParallelConfigFactory::detect())->setUsingCache(true)->setRiskyAllowed(true)->setFinder(
|
||||||
$finder
|
$finder
|
||||||
)->setIndent(' ')->setLineEnding("\n");
|
)->setIndent(' ')->setLineEnding("\n");
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-03
|
|
||||||
* @time: 20:20
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
use Pattern\Creational\AbstractFactory\{NovapostDeliveryFactory, UkrpostDeliveryFactory};
|
|
||||||
use Pattern\Creational\AbstractFactory\{JustinDeliveryFactory, MeestDeliveryFactory};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $factories
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function delivery(array $factories): void
|
|
||||||
{
|
|
||||||
foreach ($factories as $factory) {
|
|
||||||
// getting the delivery service
|
|
||||||
$deliveryService = $factory->createDeliveryService();
|
|
||||||
// getting the parcel
|
|
||||||
$package = $factory->createPackage();
|
|
||||||
// checking the parcel
|
|
||||||
$package->getConsist();
|
|
||||||
// sending the parcel
|
|
||||||
$deliveryService->sendPackage($package);
|
|
||||||
echo '<hr/>' . PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$factories = [
|
|
||||||
new MeestDeliveryFactory(),
|
|
||||||
new NovapostDeliveryFactory(),
|
|
||||||
new JustinDeliveryFactory(),
|
|
||||||
new UkrpostDeliveryFactory(),
|
|
||||||
];
|
|
||||||
|
|
||||||
delivery($factories);
|
|
@ -7,7 +7,7 @@
|
|||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"App\\Tests\\": "tests/"
|
"Tests\\": "tests/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"authors": [
|
"authors": [
|
||||||
@ -18,9 +18,13 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "8.3.*",
|
"php": "8.3.*",
|
||||||
"ext-simplexml": "*"
|
"ext-pdo": "*",
|
||||||
|
"ext-simplexml": "*",
|
||||||
|
"phpfui/orm": "^2.0",
|
||||||
|
"nesbot/carbon": "^3.10"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"roave/security-advisories": "dev-latest",
|
||||||
"friendsofphp/php-cs-fixer": "^3.76",
|
"friendsofphp/php-cs-fixer": "^3.76",
|
||||||
"phpunit/phpunit": "^12.2"
|
"phpunit/phpunit": "^12.2"
|
||||||
},
|
},
|
||||||
|
2037
composer.lock
generated
2037
composer.lock
generated
File diff suppressed because it is too large
Load Diff
11
config/database.php
Normal file
11
config/database.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 18:03
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
@ -2,6 +2,7 @@
|
|||||||
$time_start = microtime(true);
|
$time_start = microtime(true);
|
||||||
require '../vendor/autoload.php';
|
require '../vendor/autoload.php';
|
||||||
require '../src/helpers.php';
|
require '../src/helpers.php';
|
||||||
|
(new \Controller\DotEnvEnvironment())->load(__DIR__ . '/../');
|
||||||
?><!doctype html>
|
?><!doctype html>
|
||||||
<html lang="uk">
|
<html lang="uk">
|
||||||
<head>
|
<head>
|
||||||
|
39
resources/view/patterns/abstract-factory.php
Normal file
39
resources/view/patterns/abstract-factory.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-03
|
||||||
|
* @time: 20:20
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
use Pattern\Creational\AbstractFactory\{ParcelSender, ProvidersEnum as PostProvider};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $parcels
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function doDeliver(array $parcels): void
|
||||||
|
{
|
||||||
|
foreach ($parcels as $parcel) {
|
||||||
|
['provider' => $provider, 'destination_address' => $address] = $parcel;
|
||||||
|
$result = (new ParcelSender($provider, $address))->send();
|
||||||
|
|
||||||
|
echo $result ? "✔️ Sent successfully\n" : "❌ Sending failed\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$parcels = [
|
||||||
|
['provider' => PostProvider::NovaPost, 'destination_address' => "02020,\r\nм. Щастя, р-н ХТЗ"],
|
||||||
|
[
|
||||||
|
'provider' => PostProvider::UkrPost,
|
||||||
|
'destination_address' => "Голобородько Семен Юхимович,\r\nn02020, Львівська обл.,\r\nм. Городок, вул. Головна, буд. 1, кв. 50",
|
||||||
|
],
|
||||||
|
['provider' => PostProvider::Meest, 'destination_address' => "Адреса 3"],
|
||||||
|
['provider' => PostProvider::Justin, 'destination_address' => "Відділення 777"],
|
||||||
|
];
|
||||||
|
|
||||||
|
doDeliver($parcels);
|
34
resources/view/patterns/observer.php
Normal file
34
resources/view/patterns/observer.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 15:35
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
use Pattern\Behavioral\Observer\User;
|
||||||
|
use Pattern\Behavioral\Observer\UserObserver;
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
|
||||||
|
/** These names will be skipped and not be added to the log of names */
|
||||||
|
$user->setName("Just a name");
|
||||||
|
$user->setName("Some new name");
|
||||||
|
|
||||||
|
$userObserver = new UserObserver();
|
||||||
|
$user->attach($userObserver);
|
||||||
|
|
||||||
|
$user->setName("Another new name");
|
||||||
|
$user->setName("Once again new name");
|
||||||
|
$user->setName("Possibly other new name");
|
||||||
|
|
||||||
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
|
dump(
|
||||||
|
getenv('APP_ENV'),
|
||||||
|
["Another new name", "Once again new name", "Possibly other new name"],
|
||||||
|
$userObserver->getNamesLog(),
|
||||||
|
["Another new name", "Once again new name", "Possibly other new name"] === $userObserver->getNamesLog()
|
||||||
|
);
|
14
resources/view/principles/liskov-substitution.php
Normal file
14
resources/view/principles/liskov-substitution.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 08:36
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
use Pattern\SOLID\LiskovSubstitution\Bird;
|
||||||
|
|
||||||
|
$bird = new Bird;
|
23
resources/view/principles/open-closed.php
Normal file
23
resources/view/principles/open-closed.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 05:52
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
// Separate extensible behaviour behind an interface, and flip the dependencies
|
||||||
|
|
||||||
|
use Pattern\SOLID\OpenClosed\Figures\AreaCalculator;
|
||||||
|
use Pattern\SOLID\OpenClosed\Figures\Circle;
|
||||||
|
use Pattern\SOLID\OpenClosed\Figures\Square;
|
||||||
|
|
||||||
|
$circle = new Circle(3);
|
||||||
|
$square = new Square(2, 5);
|
||||||
|
$areaCalculator = new AreaCalculator;
|
||||||
|
|
||||||
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
|
dump('Circle(3)', $areaCalculator->calculate([$circle, $square]));
|
22
resources/view/principles/solid-single-responsibility.php
Normal file
22
resources/view/principles/solid-single-responsibility.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 00:04
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Pattern\SOLID\SingleResponsibility\HtmlOutput;
|
||||||
|
use Pattern\SOLID\SingleResponsibility\SalesReporter;
|
||||||
|
use Pattern\SOLID\SingleResponsibility\SalesRepository;
|
||||||
|
|
||||||
|
$now = Carbon::now();
|
||||||
|
$report = new SalesReporter(new SalesRepository);
|
||||||
|
|
||||||
|
$output = $report->between($now->clone()->subDays(10)->format('Y-m-d'), $now->format('Y-m-d'), new HtmlOutput);
|
||||||
|
|
||||||
|
echo($output);
|
32
resources/view/tools/itterate.php
Normal file
32
resources/view/tools/itterate.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 02:48
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
$c = 0;
|
||||||
|
$ite = new RecursiveDirectoryIterator('k:\tmp\faker_dir');
|
||||||
|
//$ite = new RecursiveDirectoryIterator('c:\tmp\Laracasts\Languages');
|
||||||
|
//$ite = new RecursiveDirectoryIterator('w:\tmp\Laracasts\Languages\PHP');
|
||||||
|
|
||||||
|
foreach (new RecursiveIteratorIterator($ite) as $filename => $cur) {
|
||||||
|
$pathInfo = pathinfo($filename);
|
||||||
|
|
||||||
|
if ($pathInfo['extension'] !== 'mp4') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lnkFile = $filename . '.LNK';
|
||||||
|
if (! file_exists($lnkFile)) {
|
||||||
|
symlink($filename, $lnkFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($lnkFile)) {
|
||||||
|
echo "<p>deleted $filename</p>";
|
||||||
|
//unlink($filename);
|
||||||
|
}
|
||||||
|
}
|
34
src/Controller/DotEnvEnvironment.php
Normal file
34
src/Controller/DotEnvEnvironment.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 16:23
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Controller;
|
||||||
|
|
||||||
|
class DotEnvEnvironment
|
||||||
|
{
|
||||||
|
public function load($path): void
|
||||||
|
{
|
||||||
|
$lines = file($path . '/.env');
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$split_line = explode('=', $line, 2);
|
||||||
|
if (count($split_line) !== 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
[$key, $value] = $split_line;
|
||||||
|
$key = trim($key);
|
||||||
|
$value = trim($value);
|
||||||
|
|
||||||
|
putenv(sprintf('%s=%s', $key, $value));
|
||||||
|
$_ENV[$key] = $value;
|
||||||
|
$_SERVER[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
148
src/Database/Adapter/PDO.php
Normal file
148
src/Database/Adapter/PDO.php
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Database\Adapter;
|
||||||
|
|
||||||
|
use PDOException;
|
||||||
|
use RuntimeException;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
final class PDO
|
||||||
|
{
|
||||||
|
private ?\PDO $connection = null;
|
||||||
|
private $statement = null;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $hostname,
|
||||||
|
string $username,
|
||||||
|
string $password,
|
||||||
|
string $database,
|
||||||
|
string $port = '3306'
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
$this->connection = new \PDO(
|
||||||
|
"mysql:host=" . $hostname . ";port=" . $port . ";dbname=" . $database,
|
||||||
|
$username,
|
||||||
|
$password,
|
||||||
|
[\PDO::ATTR_PERSISTENT => true]
|
||||||
|
);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
throw new RuntimeException('Failed to connect to database. Reason: \'' . $e->getMessage() . '\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->connection->exec("SET NAMES 'utf8'");
|
||||||
|
$this->connection->exec("SET CHARACTER SET utf8");
|
||||||
|
$this->connection->exec("SET CHARACTER_SET_CONNECTION=utf8");
|
||||||
|
$this->connection->exec("SET SQL_MODE = ''");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bindParam($parameter, $variable, $data_type = \PDO::PARAM_STR, $length = 0): void
|
||||||
|
{
|
||||||
|
if ($length) {
|
||||||
|
$this->statement->bindParam($parameter, $variable, $data_type, $length);
|
||||||
|
} else {
|
||||||
|
$this->statement->bindParam($parameter, $variable, $data_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function query($sql, $params = []): stdClass
|
||||||
|
{
|
||||||
|
$this->statement = $this->connection->prepare($sql);
|
||||||
|
|
||||||
|
$result = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($this->statement && $this->statement->execute($params)) {
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
while ($row = $this->statement->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = new stdClass();
|
||||||
|
$result->row = ($data[0] ?? []);
|
||||||
|
$result->rows = $data;
|
||||||
|
$result->num_rows = $this->statement->rowCount();
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
'Error: ' . $e->getMessage() . ' Error Code : ' . $e->getCode() . ' <br />' . $sql
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = new stdClass();
|
||||||
|
$result->row = [];
|
||||||
|
$result->rows = [];
|
||||||
|
$result->num_rows = 0;
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prepare($sql): void
|
||||||
|
{
|
||||||
|
$this->statement = $this->connection->prepare($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($this->statement && $this->statement->execute()) {
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
while ($row = $this->statement->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpObjectFieldsAreOnlyWrittenInspection */
|
||||||
|
$result = new stdClass();
|
||||||
|
$result->row = $data[0] ?? [];
|
||||||
|
$result->rows = $data;
|
||||||
|
$result->num_rows = $this->statement->rowCount();
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
throw new RuntimeException('Error: ' . $e->getMessage() . ' Error Code : ' . $e->getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function escape($value): array|string
|
||||||
|
{
|
||||||
|
return str_replace(
|
||||||
|
["\\", "\0", "\n", "\r", "\x1a", "'", '"'],
|
||||||
|
["\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'],
|
||||||
|
$value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function countAffected(): int
|
||||||
|
{
|
||||||
|
if ($this->statement) {
|
||||||
|
return $this->statement->rowCount();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastId(): false|string
|
||||||
|
{
|
||||||
|
return $this->connection->lastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isConnected(): bool
|
||||||
|
{
|
||||||
|
if ($this->connection) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
$this->connection = null;
|
||||||
|
}
|
||||||
|
}
|
BIN
src/Database/Adapter/db.zip
Normal file
BIN
src/Database/Adapter/db.zip
Normal file
Binary file not shown.
105
src/Database/DB.php
Normal file
105
src/Database/DB.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package OpenCart
|
||||||
|
* @author Daniel Kerr
|
||||||
|
* @copyright Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/)
|
||||||
|
* @license https://opensource.org/licenses/GPL-3.0
|
||||||
|
* @link https://www.opencart.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Database;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB class
|
||||||
|
*/
|
||||||
|
class DB
|
||||||
|
{
|
||||||
|
private mixed $adaptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param string $adaptor
|
||||||
|
* @param string $hostname
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @param string $database
|
||||||
|
* @param int|null $port
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
string $adaptor,
|
||||||
|
string $hostname,
|
||||||
|
string $username,
|
||||||
|
string $password,
|
||||||
|
string $database,
|
||||||
|
int $port = null
|
||||||
|
) {
|
||||||
|
$class = 'DB\\' . $adaptor;
|
||||||
|
|
||||||
|
if (class_exists($class)) {
|
||||||
|
$this->adaptor = new $class($hostname, $username, $password, $database, $port);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException('Error: Could not load database adaptor ' . $adaptor . '!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $sql
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function query(string $sql): array
|
||||||
|
{
|
||||||
|
return $this->adaptor->query($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function escape(string $value): string
|
||||||
|
{
|
||||||
|
return $this->adaptor->escape($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function countAffected(): int
|
||||||
|
{
|
||||||
|
return $this->adaptor->countAffected();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLastId(): int
|
||||||
|
{
|
||||||
|
return $this->adaptor->getLastId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function connected(): bool
|
||||||
|
{
|
||||||
|
return $this->adaptor->connected();
|
||||||
|
}
|
||||||
|
}
|
15
src/FileSystem/ItterateFiles.php
Normal file
15
src/FileSystem/ItterateFiles.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 02:47
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace FileSystem;
|
||||||
|
|
||||||
|
class ItterateFiles {
|
||||||
|
}
|
@ -75,7 +75,6 @@ class User implements SplSubject
|
|||||||
{
|
{
|
||||||
/** @var SplObserver $observer */
|
/** @var SplObserver $observer */
|
||||||
foreach ($this->observers as $observer) {
|
foreach ($this->observers as $observer) {
|
||||||
var_dump($observer);
|
|
||||||
$observer->update($this);
|
$observer->update($this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:07
|
* @time: 20:07
|
||||||
@ -19,7 +19,7 @@ interface AbstractFactoryInterface
|
|||||||
public function createDeliveryService(): DeliveryServiceInterface;
|
public function createDeliveryService(): DeliveryServiceInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return PackageInterface
|
* @return ParcelInterface
|
||||||
*/
|
*/
|
||||||
public function createPackage(): PackageInterface;
|
public function createParcel(): ParcelInterface;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parcel: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-08
|
||||||
|
* @time: 10:59
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
class DeliveryServiceFactory
|
||||||
|
{
|
||||||
|
public static function create(ProvidersEnum $provider): AbstractFactoryInterface
|
||||||
|
{
|
||||||
|
return $provider->getService();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:02
|
* @time: 20:02
|
||||||
@ -13,5 +13,5 @@ namespace Pattern\Creational\AbstractFactory;
|
|||||||
|
|
||||||
interface DeliveryServiceInterface
|
interface DeliveryServiceInterface
|
||||||
{
|
{
|
||||||
public function sendPackage(PackageInterface $package): void;
|
public function sendParcel(ParcelInterface $parcel): bool;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:15
|
* @time: 20:15
|
||||||
@ -18,8 +18,8 @@ class JustinDeliveryFactory implements AbstractFactoryInterface
|
|||||||
return new JustinDeliveryService();
|
return new JustinDeliveryService();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPackage(): PackageInterface
|
public function createParcel(): ParcelInterface
|
||||||
{
|
{
|
||||||
return new JustinPackage();
|
return new JustinParcel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 19:57
|
* @time: 19:57
|
||||||
@ -13,9 +13,11 @@ namespace Pattern\Creational\AbstractFactory;
|
|||||||
|
|
||||||
class JustinDeliveryService implements DeliveryServiceInterface
|
class JustinDeliveryService implements DeliveryServiceInterface
|
||||||
{
|
{
|
||||||
public function sendPackage(PackageInterface $package): void
|
public function sendParcel(ParcelInterface $parcel): bool
|
||||||
{
|
{
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
dump("Sending package via Justin...");
|
dump("Sending parcel via Justin...");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:00
|
* @time: 20:00
|
||||||
@ -11,11 +11,18 @@ declare(strict_types = 1);
|
|||||||
|
|
||||||
namespace Pattern\Creational\AbstractFactory;
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
class JustinPackage implements PackageInterface
|
class JustinParcel implements ParcelInterface
|
||||||
{
|
{
|
||||||
public function getConsist(): void
|
public function getConsist(): void
|
||||||
{
|
{
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
dump('Checking package from Justin...');
|
dump('Checking parcel from Justin...');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDestination(string $destination): static
|
||||||
|
{
|
||||||
|
echo "<pre>$destination</pre></<br>>";
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:15
|
* @time: 20:15
|
||||||
@ -18,8 +18,8 @@ class MeestDeliveryFactory implements AbstractFactoryInterface
|
|||||||
return new MeestDeliveryService();
|
return new MeestDeliveryService();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPackage(): PackageInterface
|
public function createParcel(): ParcelInterface
|
||||||
{
|
{
|
||||||
return new MeestPackage();
|
return new MeestParcel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 19:57
|
* @time: 19:57
|
||||||
@ -14,9 +14,11 @@ namespace Pattern\Creational\AbstractFactory;
|
|||||||
|
|
||||||
class MeestDeliveryService implements DeliveryServiceInterface
|
class MeestDeliveryService implements DeliveryServiceInterface
|
||||||
{
|
{
|
||||||
public function sendPackage(PackageInterface $package): void
|
public function sendParcel(ParcelInterface $parcel): bool
|
||||||
{
|
{
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
dump("Sending package via Meest...");
|
dump("Sending parcel via Meest...");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-03
|
|
||||||
* @time: 20:00
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
class MeestPackage implements PackageInterface
|
|
||||||
{
|
|
||||||
public function getConsist(): void
|
|
||||||
{
|
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
|
||||||
dump('Checking package from Meest...');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:00
|
* @time: 20:00
|
||||||
@ -11,11 +11,18 @@ declare(strict_types = 1);
|
|||||||
|
|
||||||
namespace Pattern\Creational\AbstractFactory;
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
class UkrpostPackage implements PackageInterface
|
class MeestParcel implements ParcelInterface
|
||||||
{
|
{
|
||||||
public function getConsist(): void
|
public function getConsist(): void
|
||||||
{
|
{
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
dump('Checking package from Ukrpost...');
|
dump('Checking parcel from Meest...');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDestination(string $destination): static
|
||||||
|
{
|
||||||
|
echo "<pre>$destination</pre></<br>";
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:15
|
* @time: 20:15
|
||||||
@ -15,11 +15,11 @@ class NovapostDeliveryFactory implements AbstractFactoryInterface
|
|||||||
{
|
{
|
||||||
public function createDeliveryService(): DeliveryServiceInterface
|
public function createDeliveryService(): DeliveryServiceInterface
|
||||||
{
|
{
|
||||||
return new NovapostDeliveryService();
|
return new NovapostDeliveryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPackage(): PackageInterface
|
public function createParcel(): ParcelInterface
|
||||||
{
|
{
|
||||||
return new NovapostPackage();
|
return new NovapostParcel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 19:57
|
* @time: 19:57
|
||||||
@ -13,9 +13,11 @@ namespace Pattern\Creational\AbstractFactory;
|
|||||||
|
|
||||||
class NovapostDeliveryService implements DeliveryServiceInterface
|
class NovapostDeliveryService implements DeliveryServiceInterface
|
||||||
{
|
{
|
||||||
public function sendPackage(PackageInterface $package): void
|
public function sendParcel(ParcelInterface $parcel): true
|
||||||
{
|
{
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
dump("Sending package via Novapost...");
|
dump("Sending parcel via Novapost...");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-03
|
|
||||||
* @time: 20:00
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
class NovapostPackage implements PackageInterface
|
|
||||||
{
|
|
||||||
public function getConsist(): void
|
|
||||||
{
|
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
|
||||||
dump('Checking package from Novapost...');
|
|
||||||
}
|
|
||||||
}
|
|
33
src/Pattern/Creational/AbstractFactory/NovapostParcel.php
Normal file
33
src/Pattern/Creational/AbstractFactory/NovapostParcel.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parcel: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-03
|
||||||
|
* @time: 20:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
class NovapostParcel implements ParcelInterface
|
||||||
|
{
|
||||||
|
public function getConsist(): void
|
||||||
|
{
|
||||||
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
|
dump('Checking parcel from Novapost...');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $destination
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setDestination(string $destination): static
|
||||||
|
{
|
||||||
|
echo "<pre>$destination</pre></<br>";
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package: patterns
|
|
||||||
* @author: Yevhen Odynets
|
|
||||||
* @date: 2025-07-03
|
|
||||||
* @time: 19:59
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace Pattern\Creational\AbstractFactory;
|
|
||||||
|
|
||||||
interface PackageInterface
|
|
||||||
{
|
|
||||||
public function getConsist(): void;
|
|
||||||
}
|
|
27
src/Pattern/Creational/AbstractFactory/ParcelInterface.php
Normal file
27
src/Pattern/Creational/AbstractFactory/ParcelInterface.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parcel: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-03
|
||||||
|
* @time: 19:59
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
interface ParcelInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function getConsist(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $destination
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setDestination(string $destination): static;
|
||||||
|
}
|
41
src/Pattern/Creational/AbstractFactory/ParcelSender.php
Normal file
41
src/Pattern/Creational/AbstractFactory/ParcelSender.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-08
|
||||||
|
* @time: 11:14
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
readonly class ParcelSender
|
||||||
|
{
|
||||||
|
private AbstractFactoryInterface $service;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private ProvidersEnum $provider,
|
||||||
|
private string $destinationAddress,
|
||||||
|
) {
|
||||||
|
$this->service = DeliveryServiceFactory::create($this->provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send(): bool
|
||||||
|
{
|
||||||
|
// getting the delivery service
|
||||||
|
$deliveryService = $this->service->createDeliveryService();
|
||||||
|
|
||||||
|
// getting the parcel
|
||||||
|
$parcel = $this->service->createParcel();
|
||||||
|
|
||||||
|
// setting up address & checking the parcel
|
||||||
|
$parcel->setDestination($this->destinationAddress)->getConsist();
|
||||||
|
|
||||||
|
// sending the parcel
|
||||||
|
$deliveryService->sendParcel($parcel);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
30
src/Pattern/Creational/AbstractFactory/ProvidersEnum.php
Normal file
30
src/Pattern/Creational/AbstractFactory/ProvidersEnum.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parcel: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-08
|
||||||
|
* @time: 10:20
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
enum ProvidersEnum
|
||||||
|
{
|
||||||
|
case NovaPost;
|
||||||
|
case UkrPost;
|
||||||
|
case Meest;
|
||||||
|
case Justin;
|
||||||
|
|
||||||
|
public function getService(): AbstractFactoryInterface
|
||||||
|
{
|
||||||
|
return match ($this) {
|
||||||
|
self::NovaPost => new NovapostDeliveryFactory,
|
||||||
|
self::UkrPost => new UkrpostDeliveryFactory,
|
||||||
|
self::Meest => new MeestDeliveryFactory,
|
||||||
|
self::Justin => new JustinDeliveryFactory,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 20:15
|
* @time: 20:15
|
||||||
@ -18,8 +18,8 @@ class UkrpostDeliveryFactory implements AbstractFactoryInterface
|
|||||||
return new UkrpostDeliveryService();
|
return new UkrpostDeliveryService();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createPackage(): PackageInterface
|
public function createParcel(): ParcelInterface
|
||||||
{
|
{
|
||||||
return new UkrpostPackage();
|
return new UkrpostParcel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package: patterns
|
* @parcel: patterns
|
||||||
* @author: Yevhen Odynets
|
* @author: Yevhen Odynets
|
||||||
* @date: 2025-07-03
|
* @date: 2025-07-03
|
||||||
* @time: 19:57
|
* @time: 19:57
|
||||||
@ -13,9 +13,11 @@ namespace Pattern\Creational\AbstractFactory;
|
|||||||
|
|
||||||
class UkrpostDeliveryService implements DeliveryServiceInterface
|
class UkrpostDeliveryService implements DeliveryServiceInterface
|
||||||
{
|
{
|
||||||
public function sendPackage(PackageInterface $package): void
|
public function sendParcel(ParcelInterface $parcel): bool
|
||||||
{
|
{
|
||||||
/** @noinspection ForgottenDebugOutputInspection */
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
dump("Sending package via Ukrpost...");
|
dump("Sending parcel via Ukrpost...");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
src/Pattern/Creational/AbstractFactory/UkrpostParcel.php
Normal file
34
src/Pattern/Creational/AbstractFactory/UkrpostParcel.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parcel: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-03
|
||||||
|
* @time: 20:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\Creational\AbstractFactory;
|
||||||
|
|
||||||
|
class UkrpostParcel implements ParcelInterface
|
||||||
|
{
|
||||||
|
public function getConsist(): void
|
||||||
|
{
|
||||||
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
|
dump('Checking parcel from Ukrpost...');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $destination
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setDestination(string $destination): static
|
||||||
|
{
|
||||||
|
echo "<pre>$destination</pre></<br>";
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
22
src/Pattern/Creational/AbstractFactory/info.md
Normal file
22
src/Pattern/Creational/AbstractFactory/info.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
🧠 **Переваги цієї архітектури**
|
||||||
|
|
||||||
|
✅ Легко додати нову службу доставки
|
||||||
|
✅ Не потрібно змінювати існуючий код (принцип Open/Closed)
|
||||||
|
✅ Клієнтський код не залежить від реалізацій
|
||||||
|
✅ Можна легко замінювати служби в тестах (Mock)
|
||||||
|
|
||||||
|
|
||||||
|
🧩 **Структура оновленого коду:**
|
||||||
|
DeliveryServiceInterface — інтерфейс
|
||||||
|
|
||||||
|
{Justin|Meest|NovaPost|UkrPost}DeliveryService — реалізація
|
||||||
|
|
||||||
|
|
||||||
|
DeliveryServiceFactory — фабрика
|
||||||
|
|
||||||
|
ParcelSender — клієнтська логіка
|
||||||
|
|
||||||
|
index.php — приклад використання
|
||||||
|
|
||||||
|
|
||||||
|
Надай приклад реалізації патерну Singleton на мові програмування PHP
|
@ -53,7 +53,7 @@ class Singleton
|
|||||||
dump(trim($message . ': ' . $cls, ' :'));
|
dump(trim($message . ': ' . $cls, ' :'));
|
||||||
|
|
||||||
if (!isset(self::$instances[$cls])) {
|
if (!isset(self::$instances[$cls])) {
|
||||||
self::$instances[$cls] = new static();
|
self::$instances[$cls] = new static;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$instances[$cls];
|
return self::$instances[$cls];
|
||||||
|
20
src/Pattern/SOLID/LiskovSubstitution/Bird.php
Normal file
20
src/Pattern/SOLID/LiskovSubstitution/Bird.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 08:35
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\LiskovSubstitution;
|
||||||
|
|
||||||
|
class Bird
|
||||||
|
{
|
||||||
|
public function fly(): int
|
||||||
|
{
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
28
src/Pattern/SOLID/LiskovSubstitution/BirdRun.php
Normal file
28
src/Pattern/SOLID/LiskovSubstitution/BirdRun.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 08:30
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\LiskovSubstitution;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let q(x) be a property provable about objects x of type T.
|
||||||
|
* Then q(y) should be provable for objects y of type S where S is a subtype of T.
|
||||||
|
*
|
||||||
|
* Derived classes must be substitutable for their base classes.
|
||||||
|
*/
|
||||||
|
readonly class BirdRun
|
||||||
|
{
|
||||||
|
public function __construct(private Bird $bird) {}
|
||||||
|
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$flySpeed = $this->bird->fly();
|
||||||
|
}
|
||||||
|
}
|
30
src/Pattern/SOLID/LiskovSubstitution/Duck.php
Normal file
30
src/Pattern/SOLID/LiskovSubstitution/Duck.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 09:35
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\LiskovSubstitution;
|
||||||
|
|
||||||
|
class Duck extends Bird
|
||||||
|
{
|
||||||
|
public function fly(): int
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function swim(): int
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run(): int
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
27
src/Pattern/SOLID/LiskovSubstitution/Ostrich.php
Normal file
27
src/Pattern/SOLID/LiskovSubstitution/Ostrich.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 09:39
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\LiskovSubstitution;
|
||||||
|
|
||||||
|
use Pattern\SOLID\LiskovSubstitution\Bird;
|
||||||
|
|
||||||
|
class Ostrich extends Bird
|
||||||
|
{
|
||||||
|
public function fly(): int
|
||||||
|
{
|
||||||
|
return 0; //I am not able to fly
|
||||||
|
}
|
||||||
|
|
||||||
|
public function swim(): int
|
||||||
|
{
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
}
|
33
src/Pattern/SOLID/OpenClosed/Figures/AreaCalculator.php
Normal file
33
src/Pattern/SOLID/OpenClosed/Figures/AreaCalculator.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 05:28
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Figures;
|
||||||
|
|
||||||
|
class AreaCalculator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array $shapes
|
||||||
|
*
|
||||||
|
* @return int|float
|
||||||
|
*/
|
||||||
|
public function calculate(array $shapes, int $round_precision = 2): int|float
|
||||||
|
{
|
||||||
|
$area = [];
|
||||||
|
|
||||||
|
foreach ($shapes as $shape) {
|
||||||
|
$area[] = $shape->area();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array_sum($area);
|
||||||
|
|
||||||
|
return is_int($result) ? $result : round($result, $round_precision, PHP_ROUND_HALF_UP);
|
||||||
|
}
|
||||||
|
}
|
25
src/Pattern/SOLID/OpenClosed/Figures/Circle.php
Normal file
25
src/Pattern/SOLID/OpenClosed/Figures/Circle.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 05:32
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Figures;
|
||||||
|
|
||||||
|
class Circle implements ShapeInterface
|
||||||
|
{
|
||||||
|
public function __construct(public int|float $radius) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int|float
|
||||||
|
*/
|
||||||
|
public function area(): int|float
|
||||||
|
{
|
||||||
|
return M_PI * ($this->radius ** 2);
|
||||||
|
}
|
||||||
|
}
|
17
src/Pattern/SOLID/OpenClosed/Figures/ShapeInterface.php
Normal file
17
src/Pattern/SOLID/OpenClosed/Figures/ShapeInterface.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 05:55
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Figures;
|
||||||
|
|
||||||
|
interface ShapeInterface
|
||||||
|
{
|
||||||
|
public function area(): int|float;
|
||||||
|
}
|
25
src/Pattern/SOLID/OpenClosed/Figures/Square.php
Normal file
25
src/Pattern/SOLID/OpenClosed/Figures/Square.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 05:27
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Figures;
|
||||||
|
|
||||||
|
class Square implements ShapeInterface
|
||||||
|
{
|
||||||
|
public function __construct(public int|float $width, public int|float $height) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int|float
|
||||||
|
*/
|
||||||
|
public function area(): int|float
|
||||||
|
{
|
||||||
|
return $this->width * $this->height;
|
||||||
|
}
|
||||||
|
}
|
20
src/Pattern/SOLID/OpenClosed/Payments/CashPaymentMethod.php
Normal file
20
src/Pattern/SOLID/OpenClosed/Payments/CashPaymentMethod.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 06:20
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Payments;
|
||||||
|
|
||||||
|
class CashPaymentMethod implements PaymentMethodInterface
|
||||||
|
{
|
||||||
|
public function acceptPayment($receipt)
|
||||||
|
{
|
||||||
|
// TODO: Implement acceptPayment() method.
|
||||||
|
}
|
||||||
|
}
|
20
src/Pattern/SOLID/OpenClosed/Payments/Checkout.php
Normal file
20
src/Pattern/SOLID/OpenClosed/Payments/Checkout.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 06:19
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Payments;
|
||||||
|
|
||||||
|
class Checkout
|
||||||
|
{
|
||||||
|
public function begin(Receipt $receipt, PaymentMethodInterface $payment): void
|
||||||
|
{
|
||||||
|
$payment->acceptPayment($receipt);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 06:20
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Payments;
|
||||||
|
|
||||||
|
interface PaymentMethodInterface
|
||||||
|
{
|
||||||
|
public function acceptPayment($receipt);
|
||||||
|
}
|
14
src/Pattern/SOLID/OpenClosed/Payments/Receipt.php
Normal file
14
src/Pattern/SOLID/OpenClosed/Payments/Receipt.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 06:24
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\OpenClosed\Payments;
|
||||||
|
|
||||||
|
class Receipt {}
|
27
src/Pattern/SOLID/SingleResponsibility/HtmlOutput.php
Normal file
27
src/Pattern/SOLID/SingleResponsibility/HtmlOutput.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 03:51
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\SingleResponsibility;
|
||||||
|
?>
|
||||||
|
<style>
|
||||||
|
span {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class HtmlOutput implements SalesReportOutputInterface
|
||||||
|
{
|
||||||
|
public function output($sales): string
|
||||||
|
{
|
||||||
|
return "<h2>Sales: <span>$" . number_format($sales, 2) . "</span>></h2>";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 03:50
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\SingleResponsibility;
|
||||||
|
|
||||||
|
interface SalesReportOutputInterface
|
||||||
|
{
|
||||||
|
public function output($sales): string;
|
||||||
|
}
|
26
src/Pattern/SOLID/SingleResponsibility/SalesReporter.php
Normal file
26
src/Pattern/SOLID/SingleResponsibility/SalesReporter.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-06
|
||||||
|
* @time: 23:22
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\SingleResponsibility;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
final readonly class SalesReporter
|
||||||
|
{
|
||||||
|
public function __construct(private SalesRepository $repository) {}
|
||||||
|
|
||||||
|
public function between(string|Carbon $startDate, string|Carbon $endDate, SalesReportOutputInterface $formatter): string
|
||||||
|
{
|
||||||
|
$sales = $this->repository->between($startDate, $endDate);
|
||||||
|
|
||||||
|
return $formatter->output($sales);
|
||||||
|
}
|
||||||
|
}
|
31
src/Pattern/SOLID/SingleResponsibility/SalesRepository.php
Normal file
31
src/Pattern/SOLID/SingleResponsibility/SalesRepository.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package: patterns
|
||||||
|
* @author: Yevhen Odynets
|
||||||
|
* @date: 2025-07-07
|
||||||
|
* @time: 03:45
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Pattern\SOLID\SingleResponsibility;
|
||||||
|
|
||||||
|
class SalesRepository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Just emulate db query
|
||||||
|
*
|
||||||
|
* @param $startDate
|
||||||
|
* @param $endDate
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function between($startDate, $endDate): float
|
||||||
|
{
|
||||||
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
|
dump($startDate, $endDate);
|
||||||
|
|
||||||
|
return 192_273_221 / 100;
|
||||||
|
}
|
||||||
|
}
|
@ -44,3 +44,54 @@ function getFloatRange(): float
|
|||||||
{
|
{
|
||||||
return (float)random_int(1000, 999999) / 100;
|
return (float)random_int(1000, 999999) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten a multi-dimensional associative array with dots.
|
||||||
|
*
|
||||||
|
* @param iterable $array
|
||||||
|
* @param string $prepend
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws RandomException
|
||||||
|
*/
|
||||||
|
//function array_dot(iterable $array, string $prepend = ''): array
|
||||||
|
//{
|
||||||
|
// $results = [];
|
||||||
|
//
|
||||||
|
// $flatten = static function ($data, $prefix) use (&$results, &$flatten): void {
|
||||||
|
// foreach ($data as $key => $value) {
|
||||||
|
// $newKey = $prefix.$key;
|
||||||
|
//
|
||||||
|
// if (is_array($value) && ! empty($value)) {
|
||||||
|
// $flatten($value, $newKey.'.');
|
||||||
|
// } else {
|
||||||
|
// $results[$newKey] = $value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// $flatten($array, $prepend);
|
||||||
|
//
|
||||||
|
// return $results;
|
||||||
|
//}
|
||||||
|
|
||||||
|
function abord(int $code): void
|
||||||
|
{
|
||||||
|
$response_message = $_SERVER['SERVER_PROTOCOL'];
|
||||||
|
|
||||||
|
switch ($code) {
|
||||||
|
case 404:
|
||||||
|
$response_message .= $code . ' Not Found';
|
||||||
|
break;
|
||||||
|
case 500:
|
||||||
|
$response_message .= $code . ' Internal Server Error';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$response_message .= ' 501 Not Implemented';
|
||||||
|
throw new RandomException($response_message, $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
header($response_message);
|
||||||
|
http_response_code($code);
|
||||||
|
print($response_message);
|
||||||
|
}
|
@ -9,8 +9,36 @@
|
|||||||
|
|
||||||
declare(strict_types = 1);
|
declare(strict_types = 1);
|
||||||
|
|
||||||
preg_match('/^\/patterns\/([a-z0-9-]+)/', $_SERVER["REQUEST_URI"], $patterns);
|
$request_uri = $_SERVER["REQUEST_URI"];
|
||||||
|
const DIR_VIEW = '../resources/view';
|
||||||
|
|
||||||
if (isset($patterns[1]) && file_exists('../code/' . $patterns[1] . '.php')) {
|
$slugs = ['patterns', 'principles', 'tools'];
|
||||||
require '../code/' . $patterns[1] . '.php';
|
$regex_pattern = '/^\/(' . implode('|', $slugs) . ')\/([a-z0-9-]+)/';
|
||||||
|
|
||||||
|
if (preg_match($regex_pattern, $request_uri, $matches) && isset($matches[1])) {
|
||||||
|
|
||||||
|
[$uri, $controller, $view] = $matches;
|
||||||
|
$filepath = realpath(DIR_VIEW . $uri . '.php');
|
||||||
|
if (file_exists($filepath)) {
|
||||||
|
require $filepath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*if (preg_match($regex_pattern, $request_uri, $matches)) {
|
||||||
|
$filepath = DIR_VIEW . "$slug/" . $matches[1] . '.php';
|
||||||
|
|
||||||
|
if (isset($matches[1]) && file_exists($filepath)) {
|
||||||
|
require $filepath;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
abord(404);
|
||||||
|
} catch (RandomException $e) {
|
||||||
|
/** @noinspection ForgottenDebugOutputInspection */
|
||||||
|
// dump($e->getMessage());
|
||||||
|
///}
|
||||||
|
//}*/
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
declare(strict_types = 1);
|
declare(strict_types = 1);
|
||||||
|
|
||||||
namespace App\Tests;
|
namespace Tests;
|
||||||
|
|
||||||
use Pattern\Behavioral\Observer\User;
|
use Pattern\Behavioral\Observer\User;
|
||||||
use Pattern\Behavioral\Observer\UserObserver;
|
use Pattern\Behavioral\Observer\UserObserver;
|
||||||
@ -19,6 +19,7 @@ class ObserverTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testObserver(): void
|
public function testObserver(): void
|
||||||
{
|
{
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
|
||||||
/** These names will be skipped and not be added to the log of names */
|
/** These names will be skipped and not be added to the log of names */
|
||||||
|
Loading…
Reference in New Issue
Block a user