From 9dabeaf868518f3d29423a0d98ad5c9d9d57baa1 Mon Sep 17 00:00:00 2001 From: Osahenrumwen Aigbogun Date: Thu, 28 Dec 2023 11:35:32 +0100 Subject: [PATCH] Added Cmd to make bricks --- __internal/Brick/Api/Hook.php | 15 -- src/BobDBuilder/Cmd/Make.php | 2 + src/BobDBuilder/Cmd/Traits/Make/Brick.php | 173 +++++++++++++++++++- src/BobDBuilder/Cmd/Traits/Make/Domain.php | 3 + src/Core/Api/ApiHooks.php | 3 +- src/Libs/String/Pluralize.php | 175 +++++++++++++++++++++ src/Libs/String/unchangeable.json | 1 + 7 files changed, 355 insertions(+), 17 deletions(-) delete mode 100644 __internal/Brick/Api/Hook.php create mode 100644 src/Libs/String/Pluralize.php create mode 100644 src/Libs/String/unchangeable.json diff --git a/__internal/Brick/Api/Hook.php b/__internal/Brick/Api/Hook.php deleted file mode 100644 index 6baea12..0000000 --- a/__internal/Brick/Api/Hook.php +++ /dev/null @@ -1,15 +0,0 @@ -internal_dir = $this->plug->server->lay . "__internal" . $this->plug->s; $plug->add_arg($this, ["make:domain"], 'make_domain', 0, 1); + $plug->add_arg($this, ["make:brick"], 'make_brick', 0, 1); } public function _spin(): void { $this->tags = $this->plug->tags; + $this->brick(); $this->domain(); } diff --git a/src/BobDBuilder/Cmd/Traits/Make/Brick.php b/src/BobDBuilder/Cmd/Traits/Make/Brick.php index d87a98e..fa329b7 100644 --- a/src/BobDBuilder/Cmd/Traits/Make/Brick.php +++ b/src/BobDBuilder/Cmd/Traits/Make/Brick.php @@ -2,11 +2,182 @@ namespace BrickLayer\Lay\BobDBuilder\Cmd\Traits\Make; +use BrickLayer\Lay\Libs\LayCopyDir; +use BrickLayer\Lay\Libs\LayUnlinkDir; +use BrickLayer\Lay\Libs\String\Pluralize; + trait Brick { - // TODO: Implement feature, devs should be able to create a brick with the whole file structure set public function brick() : void { + if(!isset($this->tags['make_brick'])) + return; + + $brick = $this->tags['make_brick'][0] ?? null; + $singleton = $this->tags['make_brick'][1] ?? true; + + $talk = fn($msg) => $this->plug->write_talk($msg); + + if (!$brick) + $this->plug->write_fail("No brick specified"); + + if(is_string($singleton) && !str_starts_with($singleton, "-")) + $this->plug->write_warn("*$singleton* is not a valid tag.\n" + . "This command only accepts *BrickName* and *--n-singleton* as it's arguments"); + + if($singleton === "--n-singleton") + $singleton = false; + + $talk("- If your brick is written in plural form, it'll be converted to singular form"); + + $brick = Pluralize::to_singular(ucwords($brick)); + $brick_dir = $this->plug->server->bricks . $brick; + $exists = is_dir($brick_dir); + + if (!$this->plug->force && $exists) + $this->plug->write_fail( + "Brick directory *$brick_dir* exists already!\n" + . "If you wish to force this action, pass the tag *--force* with the command\n" + . "Note, using *--force* will delete the existing directory and this process cannot be reversed!" + ); + + if ($exists) { + $talk( + "- Directory *$brick_dir* exists but *--force* tag detected\n" + . "- Deleting existing *$brick_dir*" + ); + + new LayUnlinkDir($brick_dir); + } + + $talk("- Creating new Brick directory in *$brick_dir*"); + new LayCopyDir($this->internal_dir . "Brick", $brick_dir); + + $talk("- Creating default brick files"); + + $this->brick_default_files($brick, $brick_dir, $singleton); + } + + public function brick_default_files(string $brick, string $brick_dir, bool $singleton): void + { + $brick_plural = Pluralize::to_plural($brick); + // convert uppercase to _ and lowercase for the tables + $brick_words = preg_split('/\B(?=[A-Z])/s', $brick_plural); + $brick_table = strtolower(implode("_", $brick_words)); + + $import = ""; + $body = ""; + $brick_init = "new $brick()"; + + if($singleton) { + $import = "use BrickLayer\Lay\Core\Traits\IsSingleton;"; + $body = "use IsSingleton;"; + $brick_init = "$brick::new()"; + } + + // default api hook + file_put_contents( + $brick_dir . $this->plug->s . "Api" . $this->plug->s . "Hook.php", + <<plug->s . "model" . $this->plug->s . "$brick.php", + <<open(\$table); + + return SQL::instance(); + } + + #[ArrayShape(["code" => "int", "msg" => "string", "data" => "bool"])] + public function add(array \$columns) : array + { + \$columns['id'] = \$columns['id'] ?? 'UUID()'; + + return [ + "code" => 200, + "msg" => "Ok", + "data" => self::orm(self::\$table)->insert(\$columns) + ]; + } + } + + FILE + ); + + // default controller file + file_put_contents( + $brick_dir . $this->plug->s . "controller" . $this->plug->s . "$brick_plural.php", + <<tags['make_domain'])) + return; + $domain = $this->tags['make_domain'][0] ?? null; $pattern = $this->tags['make_domain'][1] ?? null; diff --git a/src/Core/Api/ApiHooks.php b/src/Core/Api/ApiHooks.php index 64c7020..ccf50d1 100644 --- a/src/Core/Api/ApiHooks.php +++ b/src/Core/Api/ApiHooks.php @@ -4,6 +4,7 @@ use BrickLayer\Lay\Core\Exception; use BrickLayer\Lay\Core\LayConfig; +use BrickLayer\Lay\Core\View\Domain; abstract class ApiHooks { @@ -34,7 +35,7 @@ public function hooks() : void $this->request->print_as_json(); } - public function load_brick_hooks(string ...$namespaces) : void + public final function load_brick_hooks(string ...$namespaces) : void { $bricks_root = LayConfig::server_data()->bricks; diff --git a/src/Libs/String/Pluralize.php b/src/Libs/String/Pluralize.php new file mode 100644 index 0000000..392fc04 --- /dev/null +++ b/src/Libs/String/Pluralize.php @@ -0,0 +1,175 @@ + "$1zes", + '/^(ox)$/i' => "$1en", + '/([m|l])ouse$/i' => "$1ice", + '/(matr|vert|ind)ix|ex$/i' => "$1ices", + '/(x|ch|ss|sh)$/i' => "$1es", + '/([^aeiouy]|qu)y$/i' => "$1ies", + '/(hive)$/i' => "$1s", + '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves", + '/(shea|lea|loa|thie)f$/i' => "$1ves", + '/sis$/i' => "ses", + '/([ti])um$/i' => "$1a", + '/(tomat|potat|ech|her|vet)o$/i'=> "$1oes", + '/(bu)s$/i' => "$1ses", + '/(alias)$/i' => "$1es", + '/(octop)us$/i' => "$1i", + '/(ax|test)is$/i' => "$1es", + '/(us)$/i' => "$1es", + '/s$/i' => "s", + '/$/' => "s" + ]; + + public static array $singular = [ + '/(quiz)zes$/i' => "$1", + '/(matr)ices$/i' => "$1ix", + '/(vert|ind)ices$/i' => "$1ex", + '/^(ox)en$/i' => "$1", + '/(alias)es$/i' => "$1", + '/(octop|vir)i$/i' => "$1us", + '/(cris|ax|test)es$/i' => "$1is", + '/(shoe)s$/i' => "$1", + '/(o)es$/i' => "$1", + '/(bus)es$/i' => "$1", + '/([m|l])ice$/i' => "$1ouse", + '/(x|ch|ss|sh)es$/i' => "$1", + '/(m)ovies$/i' => "$1ovie", + '/(s)eries$/i' => "$1eries", + '/([^aeiouy]|qu)ies$/i' => "$1y", + '/([lr])ves$/i' => "$1f", + '/(tive)s$/i' => "$1", + '/(hive)s$/i' => "$1", + '/(li|wi|kni)ves$/i' => "$1fe", + '/(shea|loa|lea|thie)ves$/i'=> "$1f", + '/(^analy)ses$/i' => "$1sis", + '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis", + '/([ti])a$/i' => "$1um", + '/(n)ews$/i' => "$1ews", + '/(h|bl)ouses$/i' => "$1ouse", + '/(corpse)s$/i' => "$1", + '/(us)es$/i' => "$1", + '/s$/i' => "" + ]; + + public static array $irregular = [ + 'move' => 'moves', + 'foot' => 'feet', + 'goose' => 'geese', + 'sex' => 'sexes', + 'child' => 'children', + 'man' => 'men', + 'tooth' => 'teeth', + 'person' => 'people', + 'valve' => 'valves', + 'memorandum' => 'memoranda', + 'criterion' => 'criteria', + 'phenomenon' => 'phenomena', + 'nucleus' => 'nuclei', + 'fungus' => 'fungi', + 'cactus' => 'cacti', + 'alumnus' => 'alumni', + 'die' => 'dice', + 'abacus' => 'abaci', + 'hippopotamus' => 'hippopotami', + 'automaton' => 'automata' + ]; + + /** + * All the unchangeable words after pluralization, including uncountable words. + */ + private static function unchangeable() : array + { + return json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'unchangeable.json'), true); + } + + public static function to_plural(string $string ) : string + { + // save some time in the case that singular and plural are the same + if ( in_array( strtolower( $string ), self::unchangeable() ) ) + return $string; + + + // check for irregular singular forms + foreach ( self::$irregular as $pattern => $result ) + { + $pattern = '/' . $pattern . '$/i'; + + if ( preg_match( $pattern, $string ) ) + return preg_replace( $pattern, $result, $string); + } + + // check for matches using regular expressions + foreach ( self::$plural as $pattern => $result ) + { + if ( preg_match( $pattern, $string ) ) + return preg_replace( $pattern, $result, $string ); + } + + return $string; + } + + public static function to_singular(string $string) : string + { + // save some time in the case that singular and plural are the same + if ( in_array( strtolower( $string ), self::unchangeable() ) ) + return $string; + + // check for irregular plural forms + foreach ( self::$irregular as $result => $pattern ) + { + $pattern = '/' . $pattern . '$/i'; + + if ( preg_match( $pattern, $string ) ) + return preg_replace( $pattern, $result, $string); + } + + // check for matches using regular expressions + foreach ( self::$singular as $pattern => $result ) + { + if ( preg_match( $pattern, $string ) ) + return preg_replace( $pattern, $result, $string ); + } + + return $string; + } +} \ No newline at end of file diff --git a/src/Libs/String/unchangeable.json b/src/Libs/String/unchangeable.json new file mode 100644 index 0000000..83fac2d --- /dev/null +++ b/src/Libs/String/unchangeable.json @@ -0,0 +1 @@ +["sheep","fish","deer","series","species","money","rice","information","equipment","furniture","knowledge","jewelry","homework","marketing","livestock","education","courage","bravery","luck","cowardice","greed","clarity","honesty","evidence","insurance","butter","love","news","curiosity","satisfaction","work","mud","weather","racism","sexism","patriotism","chaos","scenery","help","advice","water","fun","wisdom","silence","sugar","coal","spelling","aircraft","watercraft","hovercraft","spacecraft","salmon","trout","youth","baggage","luggage","housework","paperwork","music"] \ No newline at end of file