Update for composer branch

This commit is contained in:
Toby Zerner 2015-10-11 22:54:48 +10:30
parent 5d9d04d2ab
commit 5486cc3ed8
25 changed files with 389 additions and 228 deletions

View File

@ -2,3 +2,5 @@
composer.phar
.DS_Store
Thumbs.db
bower_components
node_modules

View File

@ -1,5 +1,21 @@
<?php
require __DIR__.'/vendor/autoload.php';
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return 'Flarum\Approval\Extension';
use Flarum\Approval\Listener;
use Illuminate\Contracts\Events\Dispatcher;
return function (Dispatcher $events) {
$events->subscribe(Listener\AddClientAssets::class);
$events->subscribe(Listener\AddPostApprovalAttributes::class);
$events->subscribe(Listener\ApproveContent::class);
$events->subscribe(Listener\HideUnapprovedContent::class);
$events->subscribe(Listener\UnapproveNewContent::class);
};

View File

@ -1,65 +0,0 @@
#!/usr/bin/env bash
base=${PWD}
if [ ! -f flarum.json ]; then
echo "Could not find flarum.json file!"
exit 1
fi
extension=$(php <<CODE
<?php
\$flarum = json_decode(file_get_contents('flarum.json'), true);
echo array_key_exists('name', \$flarum) ? \$flarum['name'] : '';
CODE
)
release=/tmp/${extension}
rm -rf ${release}
mkdir ${release}
git archive --format zip --worktree-attributes HEAD > ${release}/release.zip
cd ${release}
unzip release.zip -d ./
rm release.zip
# Delete files
rm -rf ${release}/build.sh
# Install all Composer dependencies
composer install --prefer-dist --optimize-autoloader --ignore-platform-reqs --no-dev
cd "${release}/js"
if [ -f bower.json ]; then
bower install
fi
for app in forum admin; do
cd "${release}/js"
if [ -d $app ]; then
cd $app
if [ -f bower.json ]; then
bower install
fi
npm install
gulp --production
rm -rf node_modules bower_components
fi
done
rm -rf "${release}/extensions/${extension}/js/bower_components"
wait
# Finally, create the release archive
cd ${release}
find . -type d -exec chmod 0750 {} +
find . -type f -exec chmod 0644 {} +
chmod 0775 .
zip -r ${extension}.zip ./
mv ${extension}.zip ${base}/${extension}.zip

View File

@ -1,7 +1,35 @@
{
"name": "flarum/approval",
"description": "Make discussions and posts require moderator approval.",
"type": "flarum-extension",
"license": "MIT",
"authors": [
{
"name": "Toby Zerner",
"email": "toby.zerner@gmail.com"
}
],
"support": {
"issues": "https://github.com/flarum/core/issues",
"source": "https://github.com/flarum/approval"
},
"require": {
"flarum/core": "^0.1.0-beta.3",
"flarum/flags": "^0.1.0-beta.3"
},
"autoload": {
"psr-4": {
"Flarum\\Approval\\": "src/"
}
},
"extra": {
"flarum-extension": {
"title": "Approval",
"icon": {
"name": "check",
"backgroundColor": "green",
"color": "#fff"
}
}
}
}

View File

@ -1,22 +0,0 @@
{
"name": "approval",
"title": "Approval",
"description": "Make discussions and posts require moderator approval.",
"keywords": [],
"version": "0.1.0-beta.2",
"author": {
"name": "Toby Zerner",
"email": "toby@flarum.org",
"homepage": "http://tobyzerner.com"
},
"license": "MIT",
"require": {
"flarum": ">=0.1.0-beta.2",
"reports": ">=0.1.0-beta.2"
},
"icon": {
"name": "check",
"backgroundColor": "green",
"color": "#fff"
}
}

View File

@ -1,3 +0,0 @@
bower_components
node_modules
dist

View File

@ -2,6 +2,6 @@ var gulp = require('flarum-gulp');
gulp({
modules: {
'approval': 'src/**/*.js'
'flarum/approval': 'src/**/*.js'
}
});

View File

@ -0,0 +1,34 @@
System.register('flarum/approval/main', ['flarum/extend', 'flarum/app', 'flarum/components/PermissionGrid'], function (_export) {
'use strict';
var extend, app, PermissionGrid;
return {
setters: [function (_flarumExtend) {
extend = _flarumExtend.extend;
}, function (_flarumApp) {
app = _flarumApp['default'];
}, function (_flarumComponentsPermissionGrid) {
PermissionGrid = _flarumComponentsPermissionGrid['default'];
}],
execute: function () {
app.initializers.add('approval', function () {
extend(PermissionGrid.prototype, 'replyItems', function (items) {
items.add('replyWithoutApproval', {
icon: 'check',
label: 'Reply without approval',
permission: 'discussion.replyWithoutApproval'
}, 95);
});
extend(PermissionGrid.prototype, 'moderateItems', function (items) {
items.add('approvePosts', {
icon: 'check',
label: 'Approve posts',
permission: 'discussion.approvePosts'
}, 65);
});
});
}
};
});

View File

@ -2,6 +2,6 @@ var gulp = require('flarum-gulp');
gulp({
modules: {
'approval': 'src/**/*.js'
'flarum/approval': 'src/**/*.js'
}
});

View File

@ -0,0 +1,74 @@
System.register('flarum/approval/main', ['flarum/extend', 'flarum/app', 'flarum/models/Discussion', 'flarum/models/Post', 'flarum/components/DiscussionListItem', 'flarum/components/CommentPost', 'flarum/components/Button', 'flarum/utils/PostControls'], function (_export) {
'use strict';
var extend, override, app, Discussion, Post, DiscussionListItem, CommentPost, Button, PostControls;
return {
setters: [function (_flarumExtend) {
extend = _flarumExtend.extend;
override = _flarumExtend.override;
}, function (_flarumApp) {
app = _flarumApp['default'];
}, function (_flarumModelsDiscussion) {
Discussion = _flarumModelsDiscussion['default'];
}, function (_flarumModelsPost) {
Post = _flarumModelsPost['default'];
}, function (_flarumComponentsDiscussionListItem) {
DiscussionListItem = _flarumComponentsDiscussionListItem['default'];
}, function (_flarumComponentsCommentPost) {
CommentPost = _flarumComponentsCommentPost['default'];
}, function (_flarumComponentsButton) {
Button = _flarumComponentsButton['default'];
}, function (_flarumUtilsPostControls) {
PostControls = _flarumUtilsPostControls['default'];
}],
execute: function () {
app.initializers.add('flarum-approval', function () {
Discussion.prototype.isApproved = Discussion.attribute('isApproved');
Post.prototype.isApproved = Post.attribute('isApproved');
Post.prototype.canApprove = Post.attribute('canApprove');
extend(DiscussionListItem.prototype, 'attrs', function (attrs) {
if (!this.props.discussion.isApproved()) {
attrs.className += ' DiscussionListItem--unapproved';
}
});
extend(CommentPost.prototype, 'attrs', function (attrs) {
if (!this.props.post.isApproved() && !this.props.post.isHidden()) {
attrs.className += ' CommentPost--unapproved';
}
});
extend(CommentPost.prototype, 'headerItems', function (items) {
if (!this.props.post.isApproved() && !this.props.post.isHidden()) {
items.add('unapproved', 'Awaiting Approval');
}
});
override(CommentPost.prototype, 'flagReason', function (original, flag) {
if (flag.type() === 'approval') {
return 'Awaiting approval';
}
return original(flag);
});
extend(PostControls, 'destructiveControls', function (items, post) {
if (!post.isApproved() && post.canApprove()) {
items.add('approve', m(
Button,
{ icon: 'check', onclick: PostControls.approveAction.bind(post) },
'Approve'
), 10);
}
});
PostControls.approveAction = function () {
this.save({ isApproved: true });
};
}, -10); // set initializer priority to run after reports
}
};
});

View File

@ -7,7 +7,7 @@ import CommentPost from 'flarum/components/CommentPost';
import Button from 'flarum/components/Button';
import PostControls from 'flarum/utils/PostControls';
app.initializers.add('approval', () => {
app.initializers.add('flarum-approval', () => {
Discussion.prototype.isApproved = Discussion.attribute('isApproved');
Post.prototype.isApproved = Post.attribute('isApproved');

View File

@ -1,2 +0,0 @@
approval:
# hello_world: "Hello, world!"

View File

@ -1,17 +1,20 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Migrations\Approval;
namespace Flarum\Approval\Migration;
use Flarum\Database\AbstractMigration;
use Illuminate\Database\Schema\Blueprint;
use Flarum\Migrations\Migration;
class AddIsApprovedToDiscussions extends Migration
class AddIsApprovedToDiscussions extends AbstractMigration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->schema->table('discussions', function (Blueprint $table) {
@ -19,11 +22,6 @@ class AddIsApprovedToDiscussions extends Migration
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$this->schema->table('discussions', function (Blueprint $table) {

View File

@ -1,17 +1,20 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Migrations\Approval;
namespace Flarum\Approval\Migration;
use Flarum\Database\AbstractMigration;
use Illuminate\Database\Schema\Blueprint;
use Flarum\Migrations\Migration;
class AddIsApprovedToPosts extends Migration
class AddIsApprovedToPosts extends AbstractMigration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->schema->table('posts', function (Blueprint $table) {
@ -19,11 +22,6 @@ class AddIsApprovedToPosts extends Migration
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$this->schema->table('posts', function (Blueprint $table) {

View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# This script compiles the extension so that it can be used in a Flarum
# installation. It should be run from the root directory of the extension.
base=$PWD
composer install --prefer-dist --optimize-autoloader --ignore-platform-reqs --no-dev
cd "${base}/js"
if [ -f bower.json ]; then
bower install
fi
for app in forum admin; do
cd "${base}/js"
if [ -d $app ]; then
cd $app
if [ -f bower.json ]; then
bower install
fi
npm install
gulp --production
fi
done

View File

@ -8,9 +8,9 @@
* file that was distributed with this source code.
*/
namespace Flarum\Approval\Events;
namespace Flarum\Approval\Event;
use Flarum\Core\Posts\Post;
use Flarum\Core\Post;
class PostWasApproved
{

View File

@ -1,16 +0,0 @@
<?php namespace Flarum\Approval;
use Flarum\Support\Extension as BaseExtension;
use Illuminate\Events\Dispatcher;
class Extension extends BaseExtension
{
public function listen(Dispatcher $events)
{
$events->subscribe('Flarum\Approval\Listeners\AddClientAssets');
$events->subscribe('Flarum\Approval\Listeners\AddApiAttributes');
$events->subscribe('Flarum\Approval\Listeners\HideUnapprovedContent');
$events->subscribe('Flarum\Approval\Listeners\UnapproveNewContent');
$events->subscribe('Flarum\Approval\Listeners\ApproveContent');
}
}

View File

@ -0,0 +1,48 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Approval\Listener;
use Flarum\Event\ConfigureClientView;
use Illuminate\Contracts\Events\Dispatcher;
class AddClientAssets
{
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(ConfigureClientView::class, [$this, 'addAssets']);
}
/**
* @param ConfigureClientView $event
*/
public function addAssets(ConfigureClientView $event)
{
if ($event->isForum()) {
$event->addAssets([
__DIR__.'/../../js/forum/dist/extension.js',
__DIR__.'/../../less/forum/extension.less'
]);
$event->addBootstrapper('flarum/approval/main');
$event->addTranslations('flarum-approval.forum');
}
if ($event->isAdmin()) {
$event->addAssets([
__DIR__ . '/../../js/admin/dist/extension.js'
]);
$event->addBootstrapper('flarum/approval/main');
$event->addTranslations('flarum-approval.admin');
}
}
}

View File

@ -0,0 +1,42 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Approval\Listener;
use Flarum\Event\PrepareApiAttributes;
use Flarum\Api\Serializer\DiscussionSerializer;
use Flarum\Api\Serializer\PostSerializer;
use Illuminate\Contracts\Events\Dispatcher;
class AddPostApprovalAttributes
{
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(PrepareApiAttributes::class, [$this, 'addApiAttributes']);
}
/**
* @param PrepareApiAttributes $event
*/
public function addApiAttributes(PrepareApiAttributes $event)
{
if ($event->isSerializer(DiscussionSerializer::class)
|| $event->isSerializer(PostSerializer::class)) {
$event->attributes['isApproved'] = (bool) $event->model->is_approved;
}
if ($event->isSerializer(PostSerializer::class)) {
$event->attributes['canApprove'] = (bool) $event->actor->can('approvePosts', $event->model->discussion);
}
}
}

View File

@ -1,27 +1,46 @@
<?php namespace Flarum\Approval\Listeners;
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Flarum\Events\PostWillBeSaved;
use Flarum\Approval\Events\PostWasApproved;
namespace Flarum\Approval\Listener;
use Flarum\Approval\Event\PostWasApproved;
use Flarum\Core\Access\AssertPermissionTrait;
use Flarum\Event\PostWillBeSaved;
use Illuminate\Contracts\Events\Dispatcher;
class ApproveContent
{
use AssertPermissionTrait;
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(PostWillBeSaved::class, [$this, 'approvePost']);
$events->listen(PostWasApproved::class, [$this, 'approveDiscussion']);
}
/**
* @param PostWillBeSaved $event
*/
public function approvePost(PostWillBeSaved $event)
{
$attributes = $event->data['attributes'];
$post = $event->post;
if (isset($attributes['isApproved'])) {
$post->assertCan($event->actor, 'approve');
$this->assertCan($event->actor, 'approve', $post);
$isApproved = (bool) $attributes['isApproved'];
} elseif (! empty($attributes['isHidden']) && $post->can($event->actor, 'approve')) {
} elseif (! empty($attributes['isHidden']) && $event->actor->can('approve', $post)) {
$isApproved = true;
}
@ -32,6 +51,9 @@ class ApproveContent
}
}
/**
* @param PostWasApproved $event
*/
public function approveDiscussion(PostWasApproved $event)
{
$post = $event->post;

View File

@ -1,19 +1,48 @@
<?php namespace Flarum\Approval\Listeners;
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Flarum\Events\ScopeModelVisibility;
use Flarum\Events\ScopePostVisibility;
use Flarum\Events\ScopeHiddenDiscussionVisibility;
use Flarum\Core\Discussions\Discussion;
namespace Flarum\Approval\Listener;
use Flarum\Event\ScopeModelVisibility;
use Flarum\Event\ScopePostVisibility;
use Flarum\Event\ScopeHiddenDiscussionVisibility;
use Flarum\Core\Discussion;
use Illuminate\Contracts\Events\Dispatcher;
class HideUnapprovedContent
{
/**
* @var Dispatcher
*/
protected $events;
/**
* @param Dispatcher $events
*/
public function __construct(Dispatcher $events)
{
$this->events = $events;
}
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(ScopeModelVisibility::class, [$this, 'hideUnapprovedDiscussions']);
$events->listen(ScopePostVisibility::class, [$this, 'hideUnapprovedPosts']);
}
/**
* @param ScopeModelVisibility $event
*/
public function hideUnapprovedDiscussions(ScopeModelVisibility $event)
{
if ($event->model instanceof Discussion) {
@ -24,15 +53,20 @@ class HideUnapprovedContent
$query->where('discussions.is_approved', 1)
->orWhere('start_user_id', $user->id);
event(new ScopeHiddenDiscussionVisibility($query, $user, 'discussion.editPosts'));
$this->events->fire(
new ScopeHiddenDiscussionVisibility($query, $user, 'discussion.editPosts')
);
});
}
}
}
/**
* @param ScopePostVisibility $event
*/
public function hideUnapprovedPosts(ScopePostVisibility $event)
{
if ($event->discussion->can($event->actor, 'editPosts')) {
if ($event->actor->can('editPosts', $event->discussion)) {
return;
}

View File

@ -1,24 +1,38 @@
<?php namespace Flarum\Approval\Listeners;
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Flarum\Events\PostWillBeSaved;
namespace Flarum\Approval\Listener;
use Flarum\Event\PostWillBeSaved;
use Flarum\Flags\Flag;
use Illuminate\Contracts\Events\Dispatcher;
class UnapproveNewContent
{
private $savingPost;
/**
* @param Dispatcher $events
*/
public function subscribe(Dispatcher $events)
{
$events->listen(PostWillBeSaved::class, [$this, 'unapproveNewPosts']);
}
/**
* @param PostWillBeSaved $event
*/
public function unapproveNewPosts(PostWillBeSaved $event)
{
$post = $event->post;
if (! $post->exists) {
if ($post->discussion->can($event->actor, 'replyWithoutApproval')) {
if ($event->actor->can('replyWithoutApproval', $post->discussion)) {
if ($post->is_approved === null) {
$post->is_approved = true;
}

View File

@ -1,26 +0,0 @@
<?php namespace Flarum\Approval\Listeners;
use Flarum\Events\ApiAttributes;
use Flarum\Api\Serializers\DiscussionSerializer;
use Flarum\Api\Serializers\PostSerializer;
use Illuminate\Contracts\Events\Dispatcher;
class AddApiAttributes
{
public function subscribe(Dispatcher $events)
{
$events->listen(ApiAttributes::class, [$this, 'addApiAttributes']);
}
public function addApiAttributes(ApiAttributes $event)
{
if ($event->serializer instanceof DiscussionSerializer ||
$event->serializer instanceof PostSerializer) {
$event->attributes['isApproved'] = (bool) $event->model->is_approved;
}
if ($event->serializer instanceof PostSerializer) {
$event->attributes['canApprove'] = (bool) $event->model->discussion->can($event->actor, 'approvePosts');
}
}
}

View File

@ -1,44 +0,0 @@
<?php namespace Flarum\Approval\Listeners;
use Flarum\Events\RegisterLocales;
use Flarum\Events\BuildClientView;
use Illuminate\Contracts\Events\Dispatcher;
class AddClientAssets
{
public function subscribe(Dispatcher $events)
{
$events->listen(RegisterLocales::class, [$this, 'addLocale']);
$events->listen(BuildClientView::class, [$this, 'addAssets']);
}
public function addLocale(RegisterLocales $event)
{
$event->addTranslations('en', __DIR__.'/../../locale/en.yml');
}
public function addAssets(BuildClientView $event)
{
$event->forumAssets([
__DIR__.'/../../js/forum/dist/extension.js',
__DIR__.'/../../less/forum/extension.less'
]);
$event->forumBootstrapper('approval/main');
$event->forumTranslations([
// 'approval.hello_world'
]);
$event->adminAssets([
__DIR__.'/../../js/admin/dist/extension.js',
__DIR__.'/../../less/admin/extension.less'
]);
$event->adminBootstrapper('approval/main');
$event->adminTranslations([
// 'approval.hello_world'
]);
}
}