Skip to content

Commit

Permalink
Add complete crud.
Browse files Browse the repository at this point in the history
  • Loading branch information
terabytesoftw committed Nov 12, 2023
1 parent 455acdf commit a90a05e
Show file tree
Hide file tree
Showing 26 changed files with 611 additions and 120 deletions.
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
"creocoder/yii2-nested-sets": "0.9.*",
"php-forge/html": "dev-main",
"sjaakp/yii2-icon": "^1.0",
"yii2-extensions/bootbox": "dev-main",
"yii2-extensions/bootstrap5":"dev-main",
"yii2-extensions/core-library": "dev-main",
"yiisoft/yii2-bootstrap5":"^2.0",
"yiisoft/yii2": "^2.2"
},
"require-dev": {
Expand Down Expand Up @@ -76,7 +77,9 @@
"sort-packages": true,
"allow-plugins": {
"yiisoft/yii2-composer": true,
"yiisoft/config": true
"yiisoft/config": true,
"composer/installers": true,
"oomphinc/composer-installers-extender": true
}
},
"scripts": {
Expand Down
12 changes: 12 additions & 0 deletions config/extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,17 @@
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'category/delete/<slug>' => 'category/delete',
'category/disable/<slug>' => 'category/disable',
'category/enable/<slug>' => 'category/enable',
'category/index/<slug>' => 'category/index',
'category/index/page/<page>/per-page/<per-page>' => 'category/index',
'category/update/<slug>' => 'category/update',
],
],
],
];
15 changes: 11 additions & 4 deletions config/params-web.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@
use Yii\Blog\UseCase\Category\CategoryController;

return [
'app.aliases' => [
'@yii-blog' => '@vendor/yii2-extensions/blog',
'@yii-blog/migration' => '@yii-blog/src/Framework/Migration',
],
'app.controllerMap' => [
'category' => [
'class' => CategoryController::class,
],
],
'app.menu.islogged' => [
[
'label' => 'Category',
'url' => ['/category/index'],
'order' => 1,
'category' => 'yii.user',
'linkOptions' => [
'data-method' => 'post',
],
],
],
'app.params' => [
'icons' => '@npm/fortawesome--fontawesome-free/svgs/{family}/{name}.svg',
],
Expand Down
2 changes: 1 addition & 1 deletion config/params-console.php → config/params.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
declare(strict_types=1);

return [
'console.aliases' => [
'app.aliases' => [
'@yii-blog' => '@vendor/yii2-extensions/blog',
'@yii-blog/migration' => '@yii-blog/src/Framework/Migration',
],
Expand Down
24 changes: 24 additions & 0 deletions src/ActiveRecord/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
namespace Yii\Blog\ActiveRecord;

use creocoder\nestedsets\NestedSetsBehavior;
use yii\behaviors\SluggableBehavior;
use Yii\Blog\BlogModule;
use Yii\Blog\Framework\Behavior\SortableBehavior;
use Yii\Blog\Query\CategoryQuery;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
use Yiisoft\Strings\Inflector;

use function preg_match;
use function preg_replace;
use function strtolower;

final class Category extends ActiveRecord
{
Expand All @@ -20,6 +27,22 @@ public function behaviors(): array
'treeAttribute' => 'tree',
],
'sorteable' => SortableBehavior::class,
'slug' => [
'class' => SluggableBehavior::class,
'attribute' => 'title',
'ensureUnique' => true,
'immutable' => true,
'slugAttribute' => 'slug',
'value' => function (): string {
$slug = (new Inflector)->toSlug($this->title);

Check failure on line 37 in src/ActiveRecord/Category.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1-ubuntu-latest

Access to an undefined property Yii\Blog\ActiveRecord\Category::$title.

Check failure on line 37 in src/ActiveRecord/Category.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1-ubuntu-latest

Access to an undefined property Yii\Blog\ActiveRecord\Category::$title.

if (preg_match(BlogModule::SLUG_PATTERN, $slug) === false) {
$slug = preg_replace('/[^a-z0-9]+/', '-', strtolower($this->title));

Check failure on line 40 in src/ActiveRecord/Category.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1-ubuntu-latest

Access to an undefined property Yii\Blog\ActiveRecord\Category::$title.

Check failure on line 40 in src/ActiveRecord/Category.php

View workflow job for this annotation

GitHub Actions / phpstan / PHP 8.1-ubuntu-latest

Access to an undefined property Yii\Blog\ActiveRecord\Category::$title.
}

return $slug;
},
],
];
}

Expand All @@ -39,6 +62,7 @@ public function scenarios(): array
parent::scenarios(),
[
'register' => ['title', 'description', 'image_file', 'slug', 'status'],
'update' => ['title', 'description', 'image_file', 'slug', 'status'],
],
);
}
Expand Down
10 changes: 10 additions & 0 deletions src/ActiveRecord/Seo.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@

final class Seo extends ActiveRecord
{
public function safeAttributes(): array
{
return [
'h1',
'title',
'keywords',
'title',
];
}

public static function tableName(): string
{
return 'seo';
Expand Down
8 changes: 4 additions & 4 deletions src/BlogModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@

final class BlogModule extends Module
{
public const PHOTO_THUMB_WIDTH = 120;
public const PHOTO_THUMB_HEIGHT = 90;
public const STATUS_OFF = 0;
public const STATUS_ON = 1;
public const PHOTO_THUMB_WIDTH = 120;
public const SLUG_PATTERN = '/^[0-9a-z-]{0,128}$/';
public const STATUS_DISABLE = 0;
public const STATUS_ACTIVE = 1;

public function __construct(
$id,
Module $module,
public readonly bool $floatLabels = true,
public readonly string $slugPattern = '/^[0-9a-z-]{0,128}$/',
array $config = [],
) {
parent::__construct($id, $module, $config);
Expand Down
60 changes: 57 additions & 3 deletions src/Framework/EventHandler/CategoryRegisterEventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
use Yii;
use yii\base\BootstrapInterface;
use yii\base\Event;
use Yii\Blog\UseCase\Category\CategoryEvent;
use Yii\Blog\UseCase\Category\Delete\DeleteAction;
use Yii\Blog\UseCase\Category\Enable\EnableAction;
use Yii\Blog\UseCase\Category\Register\RegisterAction;
use Yii\Blog\UseCase\Category\Register\RegisterEvent;
use Yii\Blog\UseCase\Category\Update\UpdateAction;
use yii\web\Application;

final class CategoryRegisterEventHandler implements BootstrapInterface
Expand All @@ -18,10 +21,45 @@ final class CategoryRegisterEventHandler implements BootstrapInterface
*/
public function bootstrap($app): void
{
Event::on(
DeleteAction::class,
CategoryEvent::AFTER_DELETE,
static function () use ($app): void {
$app->session->setFlash('success', Yii::t('yii.blog', 'Your category has been successfully deleted.'));
},
);

Event::on(
DeleteAction::class,
CategoryEvent::DELETE_ERROR,
static function () use ($app): void {
$app->session->setFlash('danger', Yii::t('yii.blog', 'Your category has not been deleted.'));
},
);

Event::on(
DeleteAction::class,
CategoryEvent::DELETE_NODE_CATEGORY,
static function () use ($app): void {
$app->session->setFlash(
'success',
Yii::t('yii.blog', 'Your category and its sub categories have been successfully deleted.'),
);
},
);

Event::on(
EnableAction::class,
CategoryEvent::AFTER_STATUS_ACTIVE,
static function () use ($app): void {
$app->session->setFlash('success', Yii::t('yii.blog', 'Your category has been successfully enabled.'));
},
);

Event::on(
RegisterAction::class,
RegisterEvent::AFTER_REGISTER,
static function (RegisterEvent $registerEvent) use ($app): void {
CategoryEvent::AFTER_REGISTER,
static function (CategoryEvent $registerEvent) use ($app): void {
match ($registerEvent->id) {
null => $app->session->setFlash(
'success',
Expand All @@ -34,5 +72,21 @@ static function (RegisterEvent $registerEvent) use ($app): void {
};
},
);

Event::on(
UpdateAction::class,
CategoryEvent::AFTER_UPDATE,
static function () use ($app): void {
$app->session->setFlash('success', Yii::t('yii.blog', 'Your category has been successfully updated.'));
},
);

Event::on(
UpdateAction::class,
CategoryEvent::NOT_FOUND,
static function () use ($app): void {
$app->session->setFlash('danger', Yii::t('yii.blog', 'Your category has not been found.'));
},
);
}
}
2 changes: 1 addition & 1 deletion src/Framework/Migration/M202411020800Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function up(): void
'lft' => $this->integer(),
'rgt' => $this->integer(),
'depth' => $this->integer(),
'status' => $this->boolean()->defaultValue(1)
'status' => $this->integer()->defaultValue(1),
],
$this->tableOptions,
);
Expand Down
40 changes: 40 additions & 0 deletions src/UseCase/Category/CategoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Yii\Blog\ActiveRecord\Category;
use Yii\CoreLibrary\Repository\FinderRepositoryInterface;
use yii\data\ArrayDataProvider;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\Controller;

final class CategoryController extends Controller
Expand All @@ -33,9 +35,47 @@ public function __construct(
public function actions(): array
{
return [
'delete' => [
'class' => Delete\DeleteAction::class,
],
'disable' => [
'class' => Disable\DisableAction::class,
],
'enable' => [
'class' => Enable\EnableAction::class,
],
'register' => [
'class' => Register\RegisterAction::class,
],
'update' => [
'class' => Update\UpdateAction::class,
],
];
}

public function behaviors(): array
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'actions' => ['delete', 'disable', 'enable', 'index', 'register', 'update'],
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::class,
'actions' => [
'delete' => ['post'],
'disable' => ['post'],
'enable' => ['post'],
'register' => ['post'],
'update' => ['post'],
],
],
];
}

Expand Down
29 changes: 29 additions & 0 deletions src/UseCase/Category/CategoryEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Yii\Blog\UseCase\Category;

use yii\base\Event;

final class CategoryEvent extends Event
{
public const AFTER_DELETE = 'afterDelete';
public const AFTER_REGISTER = 'afterRegister';
public const AFTER_STATUS_ACTIVE = 'afterStatusActive';
public const AFTER_STATUS_DISABLE = 'afterStatusDisable';
public const AFTER_UPDATE = 'afterUpdate';
public const BEFORE_DELETE = 'beforeDelete';
public const BEFORE_REGISTER = 'beforeRegister';
public const BEFORE_STATUS_ACTIVE = 'beforeStatusActive';
public const BEFORE_STATUS_DISABLE = 'beforeStatusDisable';
public const BEFORE_UPDATE = 'beforeUpdate';
public const DELETE_ERROR = 'deleteError';
public const DELETE_NODE_CATEGORY = 'deleteNodeCategory';
public const NOT_FOUND = 'notFound';
public const NOT_UPDATE = 'notUpdate';

public function __construct(public readonly string|int|null $id = null)
{
}
}
27 changes: 12 additions & 15 deletions src/UseCase/Category/CategoryForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ final class CategoryForm extends Model
public int|null $status = null;
public string $parent = '';

public function __construct(private readonly BlogModule $blogModule, array $config = [])
{
public function __construct(
private readonly BlogModule $blogModule,
private readonly string $action,
array $config = [],
) {
parent::__construct($config);
}

Expand All @@ -46,25 +49,19 @@ public function rules(): array
'unique',
'targetClass' => Category::class,
'message' => Yii::t('yii.blog', 'This title has already been taken.'),
'when' => fn (): bool => $this->action === 'register',
],
['description', 'string', 'max' => 1024],
['image_file', 'image'],
['slug', 'string', 'max' => 128],
[
'slug',
'match',
'pattern' => $this->blogModule->slugPattern,
'message' => Yii::t('yii.blog', 'Slug can contain only 0-9, a-z and "-" characters (max: 128).'),
],
[
'slug',
'unique',
'targetClass' => Category::class,
'message' => Yii::t('yii.blog', 'This slug has already been taken.'),
],
['parent', 'string'],
['status', 'integer'],
['status', 'default', 'value' => BlogModule::STATUS_ON],
[
'status',
'default',
'value' => BlogModule::STATUS_ACTIVE,
'when' => fn (): bool => $this->action === 'register',
],
];
}
}
Loading

0 comments on commit a90a05e

Please sign in to comment.