Skip to content

Commit

Permalink
Add Favorites demo.
Browse files Browse the repository at this point in the history
  • Loading branch information
dereuromark committed Apr 4, 2024
1 parent 9b665d3 commit 9dfab49
Show file tree
Hide file tree
Showing 18 changed files with 1,500 additions and 326 deletions.
731 changes: 731 additions & 0 deletions .phpstorm.meta.php/.ide-helper.meta.php

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
"cakephp/cakephp": "^5.0.3",
"cakephp/bake": "3.x-dev as 3.0.2",
"mobiledetect/mobiledetectlib": "4.*",
"dereuromark/cakephp-favorites": "dev-master",
"dereuromark/cakephp-translate": "dev-master",
"dereuromark/cakephp-tinyauth": "dev-master",
"dereuromark/cakephp-geo": "dev-master",
"dereuromark/cakephp-shim": "dev-master as 3.1.0",
Expand Down Expand Up @@ -107,6 +109,7 @@
"bin/cake migrations migrate -p Captcha",
"bin/cake migrations migrate -p Tags",
"bin/cake migrations migrate -p Queue",
"bin/cake migrations migrate -p Favorites",
"bin/cake migrations migrate -p StateMachine"
],
"assets": [
Expand Down
659 changes: 394 additions & 265 deletions composer.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions config/app_custom.php
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,16 @@
'GoogleMap' => [
'key' => '',
],

'Favorites' => [
'models' => [
'StarPosts' => 'Sandbox.SandboxPosts',
'LikePosts' => 'Sandbox.SandboxPosts',
'FavoritePosts' => 'Sandbox.SandboxPosts',
],
'userModelClass' => 'Sandbox.SandboxUsers',
'icons' => \Favorites\View\Helper\FavoritesHelper::ICONS_GITHUB,
],
];

if (str_contains((string)getenv('DB_URL'), 'mysql')) {
Expand Down
21 changes: 21 additions & 0 deletions config/auth_acl.ini
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,24 @@ forAll = *

[StateMachine.Admin/StateMachineItemStateLogs]
* = superadmin

[Translate.Admin/Translate]
* = superadmin

[Translate.Admin/TranslateDomains]
* = superadmin

[Translate.Admin/TranslateLanguages]
* = superadmin

[Translate.Admin/TranslateTerms]
* = superadmin

[Translate.Admin/TranslateStrings]
* = superadmin

[Translate.Admin/TranslateProjects]
* = superadmin

[Translate.Admin/TranslateApiTranslations]
* = superadmin
3 changes: 3 additions & 0 deletions config/auth_allow.ini
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Sandbox.Csv = *
Sandbox.DecimalExamples = *
Sandbox.Examples = *
Sandbox.ExposeExamples = *
Sandbox.FavoriteExamples = *
Sandbox.FeedExamples = *
Sandbox.FeedbackExamples = *
Sandbox.FlashExamples = *
Expand Down Expand Up @@ -70,3 +71,5 @@ AuthSandbox.AuthSandbox = index, login, logout, register
AuthSandbox.Admin/AuthSandbox = myPublicOne

Feedback.Feedback = save, index, viewimage

Favorites.Stars = *
112 changes: 112 additions & 0 deletions plugins/Sandbox/src/Controller/FavoriteExamplesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

namespace Sandbox\Controller;

use Cake\Core\Configure;
use Cake\Event\EventInterface;
use Sandbox\Model\Entity\SandboxUser;

class FavoriteExamplesController extends SandboxAppController {

protected ?string $defaultTable = 'Sandbox.SandboxPosts';

/**
* @throws \Exception
* @return void
*/
public function initialize(): void {
parent::initialize();

$this->fetchTable('Sandbox.SandboxPosts')->ensureDemoData();

$user = $this->user();
// For demo purposes we use Configure instead of session
Configure::write('Auth.User.id', $user->id);

// You usually only need one of them per entity type
$this->loadComponent('Favorites.Starable', ['actions' => ['star']]);
$this->loadComponent('Favorites.Likeable', ['actions' => ['like']]);
$this->loadComponent('Favorites.Favoriteable', ['actions' => ['favorite']]);
}

/**
*
* @param \Cake\Event\EventInterface $event
*
* @return void
*/
public function beforeFilter(EventInterface $event) {
parent::beforeFilter($event);
}

/**
* @return void
*/
public function index() {
$user = $this->user();

$this->set(compact('user'));
}

/**
* @return \Cake\Http\Response|null|void
*/
public function star() {
$user = $this->user();
$posts = $this->fetchTable('Sandbox.SandboxPosts')->find()
->contain(['Starred'])
->all()
->toArray();

$this->set(compact('user', 'posts'));
}

/**
* @return \Cake\Http\Response|null|void
*/
public function like() {
$user = $this->user();
$posts = $this->fetchTable('Sandbox.SandboxPosts')->find()
->contain(['Liked'])
->all()
->toArray();

$this->set(compact('user', 'posts'));
}

/**
* @return \Cake\Http\Response|null|void
*/
public function favorite() {
$user = $this->user();
$posts = $this->fetchTable('Sandbox.SandboxPosts')->find()
->contain(['Favorite'])
->all()
->toArray();

$this->set(compact('user', 'posts'));
}

/**
* @return \Sandbox\Model\Entity\SandboxUser
*/
protected function user(): SandboxUser {
// For the demo we bind it to the user session to avoid other people testing it to have side-effects :)
$sid = $this->request->getSession()->id() ?: env('REMOTE_ADDR');
$user = $this->fetchTable('Sandbox.SandboxUsers')->find()
->where(['email' => $sid . '@example.de'])
->first();
if (!$user) {
$user = $this->fetchTable('Sandbox.SandboxUsers')->newEntity([
'username' => 'DemoUser',
'slug' => 'demo-user',
'email' => $sid . '@example.de',
'password' => '',
]);
$this->fetchTable('Sandbox.SandboxUsers')->saveOrFail($user);
}

return $user;
}

}
10 changes: 0 additions & 10 deletions plugins/Sandbox/src/Controller/PluginsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@ public function viewClasses(): array {
return [PdfView::class];
}

/**
* @return void
*/
public function initialize(): void {
parent::initialize();

//$this->components()->unload('RequestHandler');
//$this->loadComponent('RequestHandler', ['viewClassMap' => ['pdf' => 'CakePdf.Pdf']]);
}

/**
* Overview
*
Expand Down
52 changes: 1 addition & 51 deletions plugins/Sandbox/src/Controller/TagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function select() {
*/
public function search() {
$this->loadModel('Sandbox.SandboxPosts');
$this->ensurePostsDemoData();
$this->SandboxPosts->ensureDemoData();

$query = $this->SandboxPosts->find('search', search: $this->request->getQuery())->contain(['Tags']);

Expand Down Expand Up @@ -146,54 +146,4 @@ public function cloud() {
$this->set(compact('tags'));
}

/**
* TODO
*
* @return void
*/
protected function ensureDemoData() {
//$result = $this->SandboxCategories->Tags->find()->toArray();

$categories = $this->SandboxCategories->find()->all()->toArray();
foreach ($categories as $category) {

}
}

/**
* @return void
*/
protected function ensurePostsDemoData() {
$hasRecords = (bool)$this->SandboxPosts->find()->where(['title' => 'Awesome Post'])->first();
if ($hasRecords) {
return;
}

$posts = [
[
'title' => 'Awesome Post',
'content' => '...',
'tag_list' => 'Shiny, New, Interesting',
],
[
'title' => 'Fun Story',
'content' => '...',
'tag_list' => 'Hip, Motivating',
],
[
'title' => 'Older Post',
'content' => '...',
'tag_list' => 'Detailed, Legacy, Motivating, Long',
],
[
'title' => 'Just a Post',
'content' => '...',
],
];

$postEntities = $this->SandboxPosts->newEntities($posts);

$this->SandboxPosts->saveManyOrFail($postEntities);
}

}
37 changes: 37 additions & 0 deletions plugins/Sandbox/src/Model/Table/SandboxPostsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,41 @@ public function searchManager() {
return $searchManager;
}

/**
* @throws \Exception
* @return void
*/
public function ensureDemoData(): void {
$hasRecords = (bool)$this->find()->where(['title' => 'Awesome Post'])->first();
if ($hasRecords) {
return;
}

$posts = [
[
'title' => 'Awesome Post',
'content' => '...',
'tag_list' => 'Shiny, New, Interesting',
],
[
'title' => 'Fun Story',
'content' => '...',
'tag_list' => 'Hip, Motivating',
],
[
'title' => 'Older Post',
'content' => '...',
'tag_list' => 'Detailed, Legacy, Motivating, Long',
],
[
'title' => 'Just a Post',
'content' => '...',
],
];

$postEntities = $this->newEntities($posts);

$this->saveManyOrFail($postEntities);
}

}
42 changes: 42 additions & 0 deletions plugins/Sandbox/templates/FavoriteExamples/favorite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Sandbox\Model\Entity\SandboxPost[] $posts
*/
?>

<nav class="actions col-sm-4 col-12">
<?php echo $this->element('navigation/favorite'); ?>
</nav>
<div class="page index col-sm-8 col-12">

<h3>Likes</h3>
<p>You can allow adding custom reactions to any record with ease.</p>
<ul>
<li>Add the FavoriteableComponent to your controller</li>
<li>Add the post link icons in the frontend (e.g. using the FavoritesHelper)</li>
</ul>

<h3>Demo</h3>

<?php
foreach ($posts as $post) {
?>
<h4><?php echo h($post->title); ?></h4>
<p><?php echo $this->Favorites->widget('FavoritePosts', $post->id, $post->favorite ? $post->favorite->value : null);?></p>
<p><?php echo h($post->content) ?></p>
<?php
}
?>


<hr>

<p>Note:</p>
<ul>
<li>The examples use the native and unobstrusive UTF8 characters/emoji, but you can also use FontAwesome icons or custom HTML snippets</li>
<li>The example above is not using AJAX or JS, usually it would be advised to create a more sophisticated and user-friendly snippet here</li>
</ul>


</div>
41 changes: 41 additions & 0 deletions plugins/Sandbox/templates/FavoriteExamples/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/**
* @var \App\View\AppView $this
* @var \Sandbox\Model\Entity\SandboxUser $user
*/

$this->loadHelper('Queue.QueueProgress');
?>

<nav class="actions col-sm-4 col-12">
<?php echo $this->element('navigation/favorite'); ?>
</nav>
<div class="page index col-sm-8 col-12">

<h3>Basic Usage</h3>
<p>The most common use cases are usually</p>
<ul>
<li>Star (yes/no)</li>
<li>Like (up/down/none)</li>
<li>Favorite (some emoji or icon as reaction)</li>
</ul>

There are many implementations in modern applications:
<ul>
<li>Starred a.k.a GitHub stars (and remove star)</li>
<li>GitHub Reactions</li>
<li>Facebook Reactions</li>
<li>YouTube Likes</li>
<li>Slack Reactions</li>
<li>Reddit Votes</li>
<li>Medium Claps</li>
</ul>

<h4>Give it a try</h4>
<p>
Hello <b><?php echo h($user->username); ?></b>,
<br>the following examples will be using this account to "favorite" things.
</p>


</div>
Loading

0 comments on commit 9dfab49

Please sign in to comment.