├── .gitignore
├── LICENSE
├── README.md
├── app.dockerfile
├── application
├── .babelrc
├── .editorconfig
├── .env.example
├── .gitattributes
├── .gitignore
├── app
│ ├── Article.php
│ ├── Category.php
│ ├── Comment.php
│ ├── Console
│ │ ├── Commands
│ │ │ ├── BlogInstall.php
│ │ │ └── CreateAdmin.php
│ │ └── Kernel.php
│ ├── Discussion.php
│ ├── Exceptions
│ │ ├── Handler.php
│ │ └── UploadException.php
│ ├── Follower.php
│ ├── Helpers.php
│ ├── Http
│ │ ├── Controllers
│ │ │ ├── Api
│ │ │ │ ├── ApiController.php
│ │ │ │ ├── ArticleController.php
│ │ │ │ ├── CategoryController.php
│ │ │ │ ├── CommentController.php
│ │ │ │ ├── DiscussionController.php
│ │ │ │ ├── HomeController.php
│ │ │ │ ├── LinkController.php
│ │ │ │ ├── MeController.php
│ │ │ │ ├── SystemController.php
│ │ │ │ ├── TagController.php
│ │ │ │ ├── UploadController.php
│ │ │ │ ├── UserController.php
│ │ │ │ └── VisitorController.php
│ │ │ ├── ArticleController.php
│ │ │ ├── Auth
│ │ │ │ ├── AuthController.php
│ │ │ │ ├── ForgotPasswordController.php
│ │ │ │ ├── LoginController.php
│ │ │ │ ├── RegisterController.php
│ │ │ │ └── ResetPasswordController.php
│ │ │ ├── CategoryController.php
│ │ │ ├── Controller.php
│ │ │ ├── DiscussionController.php
│ │ │ ├── HomeController.php
│ │ │ ├── LinkController.php
│ │ │ ├── SettingController.php
│ │ │ ├── TagController.php
│ │ │ └── UserController.php
│ │ ├── Kernel.php
│ │ ├── Middleware
│ │ │ ├── EncryptCookies.php
│ │ │ ├── MustBeAdmin.php
│ │ │ ├── RedirectIfAuthenticated.php
│ │ │ ├── TrimStrings.php
│ │ │ └── VerifyCsrfToken.php
│ │ └── Requests
│ │ │ ├── ArticleRequest.php
│ │ │ ├── CategoryRequest.php
│ │ │ ├── CommentRequest.php
│ │ │ ├── DiscussionRequest.php
│ │ │ ├── ImageRequest.php
│ │ │ ├── LinkRequest.php
│ │ │ ├── TagRequest.php
│ │ │ └── UserRequest.php
│ ├── Link.php
│ ├── Notifications
│ │ ├── FollowedUser.php
│ │ ├── GotVote.php
│ │ ├── MentionedUser.php
│ │ └── ReceivedComment.php
│ ├── Policies
│ │ ├── CommentPolicy.php
│ │ ├── DiscussionPolicy.php
│ │ └── UserPolicy.php
│ ├── Providers
│ │ ├── AppServiceProvider.php
│ │ ├── AuthServiceProvider.php
│ │ ├── BroadcastServiceProvider.php
│ │ ├── EventServiceProvider.php
│ │ └── RouteServiceProvider.php
│ ├── Repositories
│ │ ├── ArticleRepository.php
│ │ ├── BaseRepository.php
│ │ ├── CategoryRepository.php
│ │ ├── CommentRepository.php
│ │ ├── DiscussionRepository.php
│ │ ├── LinkRepository.php
│ │ ├── TagRepository.php
│ │ ├── UserRepository.php
│ │ └── VisitorRepository.php
│ ├── Scopes
│ │ ├── DraftScope.php
│ │ └── StatusScope.php
│ ├── Support
│ │ ├── Response.php
│ │ └── Transform.php
│ ├── Tag.php
│ ├── Tools
│ │ ├── FileManager
│ │ │ ├── BaseManager.php
│ │ │ └── UpyunManager.php
│ │ ├── IP.php
│ │ ├── Markdowner.php
│ │ └── Mention.php
│ ├── Traits
│ │ └── FollowTrait.php
│ ├── Transformers
│ │ ├── ArticleTransformer.php
│ │ ├── CategoryTransformer.php
│ │ ├── CommentTransformer.php
│ │ ├── DiscussionTransformer.php
│ │ ├── EmptyTransformer.php
│ │ ├── LinkTransformer.php
│ │ ├── TagTransformer.php
│ │ ├── UserTransformer.php
│ │ └── VisitorTransformer.php
│ ├── User.php
│ └── Visitor.php
├── artisan
├── bootstrap
│ ├── app.php
│ ├── autoload.php
│ └── cache
│ │ └── .gitignore
├── composer.json
├── composer.lock
├── composer_install.sh
├── config
│ ├── app.php
│ ├── auth.php
│ ├── blog.php
│ ├── broadcasting.php
│ ├── cache.php
│ ├── compile.php
│ ├── database.php
│ ├── filesystems.php
│ ├── image.php
│ ├── mail.php
│ ├── queue.php
│ ├── services.php
│ ├── session.php
│ └── view.php
├── database
│ ├── .gitignore
│ ├── factories
│ │ └── ModelFactory.php
│ ├── migrations
│ │ ├── .gitkeep
│ │ ├── 2014_10_12_000000_create_users_table.php
│ │ ├── 2014_10_12_100000_create_password_resets_table.php
│ │ ├── 2016_09_02_065857_create_articles_table.php
│ │ ├── 2016_09_02_065920_create_tags_table.php
│ │ ├── 2016_09_02_065952_create_visitors_table.php
│ │ ├── 2016_09_02_070119_create_categories_table.php
│ │ ├── 2016_09_02_070132_create_discussions_table.php
│ │ ├── 2016_09_02_070151_create_comments_table.php
│ │ ├── 2016_09_13_022056_create_links_table.php
│ │ ├── 2016_11_11_163610_create_taggables_table.php
│ │ ├── 2016_12_11_153312_create_followers_table.php
│ │ ├── 2016_12_12_171655_create_notifications_table.php
│ │ ├── 2016_12_12_205419_create_failed_jobs_table.php
│ │ └── 2017_04_14_013622_create_votes_table.php
│ └── seeds
│ │ ├── .gitkeep
│ │ ├── ArticlesTableSeeder.php
│ │ ├── CategoriesTableSeeder.php
│ │ ├── CommentsTableSeeder.php
│ │ ├── DatabaseSeeder.php
│ │ ├── DiscussionsTableSeeder.php
│ │ ├── LinksTableSeeder.php
│ │ ├── TagsTableSeeder.php
│ │ ├── UsersTableSeeder.php
│ │ └── VisitorsTableSeeder.php
├── package-lock.json
├── package.json
├── phpunit.xml
├── public
│ ├── .gitignore
│ ├── .htaccess
│ ├── favicon.ico
│ ├── images
│ │ ├── default.png
│ │ └── favicon.ico
│ ├── index.php
│ └── robots.txt
├── resources
│ ├── assets
│ │ ├── js
│ │ │ ├── App.vue
│ │ │ ├── app.js
│ │ │ ├── bootstrap.js
│ │ │ ├── components
│ │ │ │ ├── AvatarUpload.vue
│ │ │ │ ├── Chartjs.vue
│ │ │ │ ├── Comment.vue
│ │ │ │ ├── Cropper.vue
│ │ │ │ ├── Parse.vue
│ │ │ │ ├── Textarea.vue
│ │ │ │ ├── VoteButton.vue
│ │ │ │ ├── dashboard
│ │ │ │ │ ├── CustomAction.vue
│ │ │ │ │ ├── Form.vue
│ │ │ │ │ ├── Modal.vue
│ │ │ │ │ ├── Table.vue
│ │ │ │ │ ├── TablePagination.vue
│ │ │ │ │ ├── TablePaginationMixin.vue
│ │ │ │ │ └── particals
│ │ │ │ │ │ ├── FooterBar.vue
│ │ │ │ │ │ ├── Navbar.vue
│ │ │ │ │ │ └── Sidebar.vue
│ │ │ │ └── passport
│ │ │ │ │ ├── AuthorizedClients.vue
│ │ │ │ │ ├── Clients.vue
│ │ │ │ │ └── PersonalAccessTokens.vue
│ │ │ ├── config
│ │ │ │ ├── base.js
│ │ │ │ ├── helper.js
│ │ │ │ ├── menu.js
│ │ │ │ └── toastr.js
│ │ │ ├── home.js
│ │ │ ├── lang
│ │ │ │ ├── en
│ │ │ │ │ ├── form.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page.js
│ │ │ │ │ ├── sidebar.js
│ │ │ │ │ └── table.js
│ │ │ │ ├── index.js
│ │ │ │ └── zh_cn
│ │ │ │ │ ├── form.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page.js
│ │ │ │ │ ├── sidebar.js
│ │ │ │ │ └── table.js
│ │ │ ├── plugins
│ │ │ │ └── http
│ │ │ │ │ └── index.js
│ │ │ ├── routes.js
│ │ │ ├── vendor
│ │ │ │ ├── github_emoji.js
│ │ │ │ ├── highlight.min.js
│ │ │ │ └── select2.min.js
│ │ │ ├── views
│ │ │ │ ├── Dashboard.vue
│ │ │ │ ├── Parent.vue
│ │ │ │ └── dashboard
│ │ │ │ │ ├── File.vue
│ │ │ │ │ ├── Home.vue
│ │ │ │ │ ├── System.vue
│ │ │ │ │ ├── Visitor.vue
│ │ │ │ │ ├── article
│ │ │ │ │ ├── Article.vue
│ │ │ │ │ ├── Create.vue
│ │ │ │ │ ├── Edit.vue
│ │ │ │ │ ├── Form.vue
│ │ │ │ │ └── FormMixin.vue
│ │ │ │ │ ├── category
│ │ │ │ │ ├── Category.vue
│ │ │ │ │ ├── Create.vue
│ │ │ │ │ ├── Edit.vue
│ │ │ │ │ └── Form.vue
│ │ │ │ │ ├── comment
│ │ │ │ │ ├── Comment.vue
│ │ │ │ │ └── Edit.vue
│ │ │ │ │ ├── discussion
│ │ │ │ │ ├── Create.vue
│ │ │ │ │ ├── Discussion.vue
│ │ │ │ │ ├── Edit.vue
│ │ │ │ │ └── Form.vue
│ │ │ │ │ ├── link
│ │ │ │ │ ├── Create.vue
│ │ │ │ │ ├── Edit.vue
│ │ │ │ │ ├── Form.vue
│ │ │ │ │ └── Link.vue
│ │ │ │ │ ├── tag
│ │ │ │ │ ├── Create.vue
│ │ │ │ │ ├── Edit.vue
│ │ │ │ │ ├── Form.vue
│ │ │ │ │ └── Tag.vue
│ │ │ │ │ └── user
│ │ │ │ │ ├── Create.vue
│ │ │ │ │ ├── Edit.vue
│ │ │ │ │ ├── Form.vue
│ │ │ │ │ └── User.vue
│ │ │ └── vuex
│ │ │ │ ├── actions.js
│ │ │ │ ├── mutations.js
│ │ │ │ └── store.js
│ │ └── sass
│ │ │ ├── _form.scss
│ │ │ ├── _ibox.scss
│ │ │ ├── _navbar.scss
│ │ │ ├── _pagination.scss
│ │ │ ├── _toastr.scss
│ │ │ ├── _togglebutton.scss
│ │ │ ├── app.scss
│ │ │ ├── comment.scss
│ │ │ ├── home.scss
│ │ │ ├── markdown.scss
│ │ │ ├── public.scss
│ │ │ ├── styles.scss
│ │ │ ├── variables.scss
│ │ │ └── vendor
│ │ │ ├── highlight.min.css
│ │ │ ├── select2.min.css
│ │ │ ├── simplemde.min.css
│ │ │ └── toastr.min.css
│ ├── lang
│ │ ├── en
│ │ │ ├── auth.php
│ │ │ ├── blog.php
│ │ │ ├── pagination.php
│ │ │ ├── passwords.php
│ │ │ └── validation.php
│ │ └── zh_cn
│ │ │ ├── auth.php
│ │ │ ├── blog.php
│ │ │ ├── pagination.php
│ │ │ ├── passwords.php
│ │ │ └── validation.php
│ └── views
│ │ ├── article
│ │ ├── index.blade.php
│ │ └── show.blade.php
│ │ ├── auth
│ │ ├── github_register.blade.php
│ │ ├── login.blade.php
│ │ ├── passwords
│ │ │ ├── email.blade.php
│ │ │ └── reset.blade.php
│ │ └── register.blade.php
│ │ ├── category
│ │ ├── index.blade.php
│ │ └── show.blade.php
│ │ ├── dashboard
│ │ └── index.blade.php
│ │ ├── discussion
│ │ ├── create.blade.php
│ │ ├── edit.blade.php
│ │ ├── index.blade.php
│ │ └── show.blade.php
│ │ ├── errors
│ │ ├── 403.blade.php
│ │ ├── 404.blade.php
│ │ └── 503.blade.php
│ │ ├── layouts
│ │ └── app.blade.php
│ │ ├── link
│ │ └── index.blade.php
│ │ ├── mail
│ │ ├── followed
│ │ │ └── user.blade.php
│ │ ├── mention
│ │ │ └── user.blade.php
│ │ └── receive
│ │ │ └── comment.blade.php
│ │ ├── notifications
│ │ ├── followed-user.blade.php
│ │ ├── got-vote.blade.php
│ │ ├── mentioned-user.blade.php
│ │ └── received-comment.blade.php
│ │ ├── pagination
│ │ └── default.blade.php
│ │ ├── particals
│ │ ├── footer.blade.php
│ │ ├── jumbotron.blade.php
│ │ └── navbar.blade.php
│ │ ├── search.blade.php
│ │ ├── setting
│ │ ├── binding.blade.php
│ │ ├── index.blade.php
│ │ ├── notification.blade.php
│ │ └── particals
│ │ │ └── sidebar.blade.php
│ │ ├── tag
│ │ ├── index.blade.php
│ │ └── show.blade.php
│ │ ├── user
│ │ ├── comments.blade.php
│ │ ├── discussions.blade.php
│ │ ├── following.blade.php
│ │ ├── index.blade.php
│ │ ├── notifications.blade.php
│ │ ├── particals
│ │ │ ├── comments.blade.php
│ │ │ ├── discussions.blade.php
│ │ │ └── info.blade.php
│ │ └── profile.blade.php
│ │ ├── vendor
│ │ └── notifications
│ │ │ ├── email-plain.blade.php
│ │ │ └── email.blade.php
│ │ └── widgets
│ │ └── article.blade.php
├── routes
│ ├── api.php
│ ├── channels.php
│ ├── console.php
│ └── web.php
├── server.php
├── storage
│ ├── app
│ │ ├── .gitignore
│ │ └── public
│ │ │ └── .gitignore
│ ├── framework
│ │ ├── .gitignore
│ │ ├── cache
│ │ │ └── .gitignore
│ │ ├── sessions
│ │ │ └── .gitignore
│ │ └── views
│ │ │ └── .gitignore
│ ├── logs
│ │ └── .gitignore
│ ├── oauth-private.key
│ └── oauth-public.key
├── tests
│ ├── CreatesApplication.php
│ ├── Feature
│ │ ├── Api
│ │ │ ├── ArticleApiTest.php
│ │ │ └── UserApiTest.php
│ │ └── ExampleTest.php
│ ├── TestCase.php
│ └── Unit
│ │ └── ExampleTest.php
├── webpack.mix.js
└── yarn.lock
├── docker-compose.yml
├── vhost.conf
└── web.dockerfile
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Gliterd Software
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app.dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:7.1.12-fpm
2 |
3 | RUN apt-get update && apt-get install -y libmcrypt-dev \
4 | mysql-client libmagickwand-dev --no-install-recommends curl nano \
5 | && pecl install imagick \
6 | && docker-php-ext-enable imagick \
7 | && docker-php-ext-install \
8 | zip xml gd \
9 | mcrypt pdo_mysql
10 |
--------------------------------------------------------------------------------
/application/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2"]
3 | }
--------------------------------------------------------------------------------
/application/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = false
10 |
11 | [*.{vue,js,scss}]
12 | charset = utf-8
13 | indent_style = space
14 | indent_size = 2
15 | end_of_line = lf
16 | insert_final_newline = true
17 | trim_trailing_whitespace = true
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/application/.env.example:
--------------------------------------------------------------------------------
1 | APP_ENV=local
2 | APP_KEY=
3 | APP_DEBUG=true
4 | APP_LOG_LEVEL=debug
5 | APP_URL=http://localhost
6 |
7 | DB_CONNECTION=mysql
8 | DB_HOST=127.0.0.1
9 | DB_PORT=3306
10 | DB_DATABASE=homestead
11 | DB_USERNAME=homestead
12 | DB_PASSWORD=secret
13 |
14 | BROADCAST_DRIVER=log
15 | CACHE_DRIVER=file
16 | SESSION_DRIVER=file
17 | QUEUE_DRIVER=sync
18 |
19 | REDIS_HOST=127.0.0.1
20 | REDIS_PASSWORD=null
21 | REDIS_PORT=6379
22 |
23 | MAIL_DRIVER=smtp
24 | MAIL_HOST=
25 | MAIL_PORT=
26 | MAIL_USERNAME=
27 | MAIL_PASSWORD=
28 | MAIL_ENCRYPTION=
29 | MAIL_FROM=Example
30 | MAIL_NAME=Example
31 |
32 | PUSHER_APP_ID=
33 | PUSHER_APP_KEY=
34 | PUSHER_APP_SECRET=
35 |
36 | GITHUB_CLIENT_ID=
37 | GITHUB_CLIENT_SECRET=
38 | GITHUB_REDIRECT=
39 |
40 | YOUDAO_APP_KEY=
41 | YOUDAO_APP_SECRET=
42 |
--------------------------------------------------------------------------------
/application/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.css linguist-vendored
3 | *.scss linguist-vendored
4 |
--------------------------------------------------------------------------------
/application/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /public/storage
3 | /vendor
4 | /.idea
5 | Homestead.json
6 | Homestead.yaml
7 | .env
8 | /public/css
9 | /public/js
10 | /public/fonts
11 | /public/mix-manifest.json
12 | npm-debug.log
--------------------------------------------------------------------------------
/application/app/Category.php:
--------------------------------------------------------------------------------
1 | hasMany(Article::Class);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/application/app/Comment.php:
--------------------------------------------------------------------------------
1 | belongsTo(User::class);
40 | }
41 |
42 | /**
43 | * Get all of the owning commentable models.
44 | *
45 | * @return \Illuminate\Database\Eloquent\Relations\morphTo
46 | */
47 | public function commentable()
48 | {
49 | return $this->morphTo();
50 | }
51 |
52 | /**
53 | * Set the content Attribute.
54 | *
55 | * @param $value
56 | */
57 | public function setContentAttribute($value)
58 | {
59 | $data = [
60 | 'raw' => $value,
61 | 'html' => (new Markdowner)->convertMarkdownToHtml($value)
62 | ];
63 |
64 | $this->attributes['content'] = json_encode($data);
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/application/app/Console/Commands/BlogInstall.php:
--------------------------------------------------------------------------------
1 | execShellWithPrettyPrint('php artisan key:generate');
39 | $this->execShellWithPrettyPrint('php artisan migrate --seed');
40 | $this->execShellWithPrettyPrint('php artisan passport:install');
41 | $this->execShellWithPrettyPrint('php artisan storage:link');
42 | }
43 |
44 | /**
45 | * Exec sheel with pretty print.
46 | *
47 | * @param string $command
48 | * @return mixed
49 | */
50 | public function execShellWithPrettyPrint($command)
51 | {
52 | $this->info('---');
53 | $this->info($command);
54 | $output = shell_exec($command);
55 | $this->info($output);
56 | $this->info('---');
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/application/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')
29 | // ->hourly();
30 | }
31 |
32 | /**
33 | * Register the Closure based commands for the application.
34 | *
35 | * @return void
36 | */
37 | protected function commands()
38 | {
39 | require base_path('routes/console.php');
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/application/app/Exceptions/Handler.php:
--------------------------------------------------------------------------------
1 | expectsJson()) {
60 | return response()->json(['error' => 'Unauthenticated.'], 401);
61 | }
62 |
63 | return redirect()->guest('login');
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/application/app/Exceptions/UploadException.php:
--------------------------------------------------------------------------------
1 | translate($slug);
54 | }
55 | }
56 |
57 | if(!function_exists('lang')) {
58 | /**
59 | * Trans for getting the language.
60 | *
61 | * @param string $text
62 | * @param array $parameters
63 | * @return string
64 | */
65 | function lang($text, $parameters = [])
66 | {
67 | return trans('blog.'.$text, $parameters);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Api/ApiController.php:
--------------------------------------------------------------------------------
1 | response = new Response(response(), new Transform($manager));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Api/HomeController.php:
--------------------------------------------------------------------------------
1 | user = $user;
26 | $this->visitor = $visitor;
27 | $this->article = $article;
28 | $this->comment = $comment;
29 | }
30 |
31 | public function statistics()
32 | {
33 | $users = $this->user->getNumber();
34 | $visitors = (int) $this->visitor->getAllClicks();
35 | $articles = $this->article->getNumber();
36 | $comments = $this->comment->getNumber();
37 |
38 | $data = compact('users', 'visitors', 'articles', 'comments');
39 |
40 | return $this->response->json($data);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Api/MeController.php:
--------------------------------------------------------------------------------
1 | comment = $comment;
17 | }
18 |
19 | /**
20 | * post up vote the comment by user.
21 | *
22 | * @param Request $request
23 | * @param string $type
24 | *
25 | * @return mixed
26 | */
27 | public function postVoteComment(Request $request, $type)
28 | {
29 | $this->validate($request, [
30 | 'id' => 'required|exists:comments,id',
31 | ]);
32 |
33 | ($type == 'up')
34 | ? $this->comment->toggleVote($request->id)
35 | : $this->comment->toggleVote($request->id, false);
36 |
37 | return $this->response->withNoContent();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Api/SystemController.php:
--------------------------------------------------------------------------------
1 | getPdo();
23 |
24 | $version = $pdo->query('select version()')->fetchColumn();
25 |
26 | $data = [
27 | 'server' => $_SERVER['SERVER_SOFTWARE'],
28 | 'http_host' => $_SERVER['HTTP_HOST'],
29 | 'remote_host' => isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : $_SERVER['REMOTE_ADDR'],
30 | 'user_agent' => $_SERVER['HTTP_USER_AGENT'],
31 | 'php' => phpversion(),
32 | 'sapi_name' => php_sapi_name(),
33 | 'extensions' => implode(", ", get_loaded_extensions()),
34 | 'db_connection' => isset($_SERVER['DB_CONNECTION']) ? $_SERVER['DB_CONNECTION'] : 'Secret',
35 | 'db_database' => isset($_SERVER['DB_DATABASE']) ? $_SERVER['DB_DATABASE'] : 'Secret',
36 | 'db_version' => $version,
37 | ];
38 |
39 | return $this->response->json($data);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Api/VisitorController.php:
--------------------------------------------------------------------------------
1 | visitor = $visitor;
16 | }
17 |
18 | /**
19 | * Display a listing of the resource.
20 | *
21 | * @return \Illuminate\Http\JsonResponse
22 | */
23 | public function index()
24 | {
25 | return $this->response->collection($this->visitor->page());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/ArticleController.php:
--------------------------------------------------------------------------------
1 | article = $article;
16 | }
17 |
18 | /**
19 | * Display the articles resource.
20 | *
21 | * @return mixed
22 | */
23 | public function index()
24 | {
25 | $articles = $this->article->page(config('blog.article.number'), config('blog.article.sort'), config('blog.article.sortColumn'));
26 |
27 | return view('article.index', compact('articles'));
28 | }
29 |
30 | /**
31 | * Display the article resource by article slug.
32 | *
33 | * @param string $slug
34 | * @return mixed
35 | */
36 | public function show($slug)
37 | {
38 | $article = $this->article->getBySlug($slug);
39 |
40 | // $article->content = collect(json_decode($article->content))->get('html');
41 |
42 | return view('article.show', compact('article'));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Auth/ForgotPasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Auth/LoginController.php:
--------------------------------------------------------------------------------
1 | middleware('guest', ['except' => 'logout']);
39 | }
40 |
41 | /**
42 | * Log the user out of the application.
43 | *
44 | * @param \Illuminate\Http\Request $request
45 | * @return \Illuminate\Http\Response
46 | */
47 | public function logout(Request $request)
48 | {
49 | $this->guard()->logout();
50 |
51 | $request->session()->flush();
52 |
53 | $request->session()->regenerate();
54 |
55 | return redirect('/login');
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Auth/ResetPasswordController.php:
--------------------------------------------------------------------------------
1 | middleware('guest');
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/CategoryController.php:
--------------------------------------------------------------------------------
1 | category = $category;
16 | }
17 |
18 | /**
19 | * Display the categories resource.
20 | *
21 | * @return mixed
22 | */
23 | public function index()
24 | {
25 | $categories = $this->category->all();
26 |
27 | return view('category.index', compact('categories'));
28 | }
29 |
30 | /**
31 | * Display the category resource by category name.
32 | *
33 | * @param string $category
34 | * @return mixed
35 | */
36 | public function show($category)
37 | {
38 | if (!$category = $this->category->getByName($category)) abort(404);
39 |
40 | $articles = $category->articles;
41 |
42 | return view('category.show', compact('category', 'articles'));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | article = $article;
16 | }
17 |
18 | /**
19 | * Display the dashboard page.
20 | *
21 | * @return mixed
22 | */
23 | public function dashboard()
24 | {
25 | return view('dashboard.index');
26 | }
27 |
28 | /**
29 | * Search the article by keyword.
30 | *
31 | * @param Request $request
32 | * @return mixed
33 | */
34 | public function search(Request $request)
35 | {
36 | $key = trim($request->get('q'));
37 |
38 | $articles = $this->article->search($key);
39 |
40 | return view('search', compact('articles'));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/LinkController.php:
--------------------------------------------------------------------------------
1 | link = $link;
16 | }
17 |
18 | /**
19 | * Display the link resource.
20 | *
21 | * @return mix
22 | */
23 | public function index()
24 | {
25 | $links = $this->link->page();
26 |
27 | return view('link.index', compact('links'));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/SettingController.php:
--------------------------------------------------------------------------------
1 | user = $user;
15 | }
16 |
17 | /**
18 | * Display the current user setting list.
19 | *
20 | * @return \Illuminate\Http\Response
21 | */
22 | public function index()
23 | {
24 | return view('setting.index');
25 | }
26 |
27 | /**
28 | * Display the notification page for setting.
29 | *
30 | * @return \Illuminate\Http\Response
31 | */
32 | public function notification()
33 | {
34 | return view('setting.notification');
35 | }
36 |
37 | /**
38 | * Set the email notification.
39 | *
40 | * @param Request $request [description]
41 | * @return Redirect
42 | */
43 | public function setNotification(Request $request)
44 | {
45 | $input = [
46 | 'email_notify_enabled' => $request->get('email_notify_enabled') ? 'yes' : 'no'
47 | ];
48 |
49 | $this->user->update(\Auth::id(), $input);
50 |
51 | return redirect()->back();
52 | }
53 |
54 | /**
55 | * Display the bindings page.
56 | *
57 | * @return \Illuminate\Http\Response
58 | */
59 | public function binding()
60 | {
61 | return view('setting.binding');
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/application/app/Http/Controllers/TagController.php:
--------------------------------------------------------------------------------
1 | tag = $tag;
16 | }
17 |
18 | /**
19 | * Display the tag resource.
20 | *
21 | * @return mixed
22 | */
23 | public function index()
24 | {
25 | $tags = $this->tag->all();
26 |
27 | return view('tag.index', compact('tags'));
28 | }
29 |
30 | /**
31 | * Display the articles and discussions by the tag.
32 | *
33 | * @param string $tag
34 | * @return mixed
35 | */
36 | public function show($tag)
37 | {
38 | $tag = $this->tag->getByName($tag);
39 |
40 | if (!$tag) abort(404);
41 |
42 | $articles = $tag->articles;
43 | $discussions = $tag->discussions;
44 |
45 | return view('tag.show', compact('tag', 'articles', 'discussions'));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/application/app/Http/Middleware/EncryptCookies.php:
--------------------------------------------------------------------------------
1 | is_admin) {
21 | abort(404);
22 | }
23 |
24 | return $next($request);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/application/app/Http/Middleware/RedirectIfAuthenticated.php:
--------------------------------------------------------------------------------
1 | check()) {
21 | return redirect('/');
22 | }
23 |
24 | return $next($request);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/application/app/Http/Middleware/TrimStrings.php:
--------------------------------------------------------------------------------
1 | 'required|min:3',
28 | 'subtitle' => 'required|min:3',
29 | 'content' => 'required',
30 | 'category_id' => 'required',
31 | 'published_at' => 'required',
32 | ];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/CategoryRequest.php:
--------------------------------------------------------------------------------
1 | 'required|min:2',
28 | 'path' => 'required',
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/CommentRequest.php:
--------------------------------------------------------------------------------
1 | 'required'
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/DiscussionRequest.php:
--------------------------------------------------------------------------------
1 | 'required|min:2',
28 | 'content' => 'required',
29 | 'tags' => 'required',
30 | ];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/ImageRequest.php:
--------------------------------------------------------------------------------
1 | 'image|mimes:jpeg,jpg,png,gif'
28 | ];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/LinkRequest.php:
--------------------------------------------------------------------------------
1 | 'required|min:2',
28 | 'link' => 'required|min:2'
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/TagRequest.php:
--------------------------------------------------------------------------------
1 | 'required|unique:tags',
28 | 'title' => 'required',
29 | 'meta_description' => 'required'
30 | ];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/application/app/Http/Requests/UserRequest.php:
--------------------------------------------------------------------------------
1 | 'required|unique:users',
28 | 'email' => 'required|email|unique:users',
29 | 'password_confirmation' => 'required',
30 | 'password' => 'required|confirmed',
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/application/app/Link.php:
--------------------------------------------------------------------------------
1 | user = $user;
27 | }
28 |
29 | /**
30 | * Get the notification's delivery channels.
31 | *
32 | * @param mixed $notifiable
33 | * @return array
34 | */
35 | public function via($notifiable)
36 | {
37 | return ['database', 'mail'];
38 | }
39 |
40 | /**
41 | * Get the mail representation of the notification.
42 | *
43 | * @param mixed $notifiable
44 | * @return \Illuminate\Notifications\Messages\MailMessage
45 | */
46 | public function toMail($notifiable)
47 | {
48 | $message = lang('Followed Content', [ 'user' => $this->user->name]);
49 |
50 | $data = [
51 | 'username' => $notifiable->name,
52 | 'message' => $message,
53 | 'url' => url('user', [ 'username' => $this->user->name ])
54 | ];
55 |
56 | return (new MailMessage)
57 | ->subject(lang('Someone Followed'))
58 | ->markdown('mail.followed.user', $data);
59 | }
60 |
61 | /**
62 | * Get the array representation of the notification.
63 | *
64 | * @param mixed $notifiable
65 | * @return array
66 | */
67 | public function toArray($notifiable)
68 | {
69 | return $this->user->toArray();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/application/app/Notifications/GotVote.php:
--------------------------------------------------------------------------------
1 | vote_type = $vote_type;
28 | $this->user = $user;
29 | $this->comment = $comment;
30 | }
31 |
32 | /**
33 | * Get the notification's delivery channels.
34 | *
35 | * @param mixed $notifiable
36 | * @return array
37 | */
38 | public function via($notifiable)
39 | {
40 | return ['database'];
41 | }
42 |
43 | /**
44 | * Get the mail representation of the notification.
45 | *
46 | * @param mixed $notifiable
47 | * @return \Illuminate\Notifications\Messages\MailMessage
48 | */
49 | public function toMail($notifiable)
50 | {
51 | return (new MailMessage)
52 | ->line('The introduction to the notification.')
53 | ->action('Notification Action', url('/'))
54 | ->line('Thank you for using our application!');
55 | }
56 |
57 | /**
58 | * Get the array representation of the notification.
59 | *
60 | * @param mixed $notifiable
61 | * @return array
62 | */
63 | public function toArray($notifiable)
64 | {
65 | return array(
66 | 'comment_id' => $this->comment->id,
67 | 'issuer_id' => $this->user->id,
68 | 'commentable_id' => $this->comment->commentable_id,
69 | 'vote_type' => $this->vote_type
70 | );
71 | }
72 | }
--------------------------------------------------------------------------------
/application/app/Policies/CommentPolicy.php:
--------------------------------------------------------------------------------
1 | is_admin || $comment->user_id === $user->id;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/application/app/Policies/DiscussionPolicy.php:
--------------------------------------------------------------------------------
1 | is_admin || $user->id === $discussion->user_id;
23 | }
24 |
25 | /**
26 | * Determine whether the user can delete the discussion.
27 | *
28 | * @param \App\User $user
29 | * @param \App\Discussion $discussion
30 | * @return mixed
31 | */
32 | public function delete(User $user, Discussion $discussion)
33 | {
34 | return $user->is_admin;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/application/app/Policies/UserPolicy.php:
--------------------------------------------------------------------------------
1 | id === $user->id;
22 | }
23 |
24 | /**
25 | * Determine whether the current user can delete the user.
26 | *
27 | * @param \App\User $currentUser
28 | * @param \App\User $user
29 | * @return mixed
30 | */
31 | public function delete(User $currentUser, User $user)
32 | {
33 | return $currentUser->is_admin;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/application/app/Providers/AppServiceProvider.php:
--------------------------------------------------------------------------------
1 | Discussion::class,
26 | 'articles' => Article::class,
27 | ]);
28 | }
29 |
30 | /**
31 | * Register any application services.
32 | *
33 | * @return void
34 | */
35 | public function register()
36 | {
37 | $this->app->singleton('uploader', function ($app) {
38 | $config = config('filesystems.default', 'public');
39 |
40 | if ($config == 'upyun') {
41 | return new UpyunManager();
42 | }
43 |
44 | return new BaseManager();
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/application/app/Providers/AuthServiceProvider.php:
--------------------------------------------------------------------------------
1 | \App\Policies\UserPolicy::class,
19 | \App\Comment::class => \App\Policies\CommentPolicy::class,
20 | \App\Discussion::class => \App\Policies\DiscussionPolicy::class,
21 | ];
22 |
23 | /**
24 | * Register any authentication / authorization services.
25 | *
26 | * @return void
27 | */
28 | public function boot()
29 | {
30 | $this->registerPolicies();
31 |
32 | Passport::routes();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/application/app/Providers/BroadcastServiceProvider.php:
--------------------------------------------------------------------------------
1 | [
17 | 'App\Listeners\EventListener',
18 | ],
19 | ];
20 |
21 | /**
22 | * Register any events for your application.
23 | *
24 | * @return void
25 | */
26 | public function boot()
27 | {
28 | parent::boot();
29 |
30 | //
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/application/app/Providers/RouteServiceProvider.php:
--------------------------------------------------------------------------------
1 | mapApiRoutes();
37 |
38 | $this->mapWebRoutes();
39 |
40 | Route::post('/oauth/token', [
41 | 'uses' => '\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken',
42 | ]);
43 | }
44 |
45 | /**
46 | * Define the "web" routes for the application.
47 | *
48 | * These routes all receive session state, CSRF protection, etc.
49 | *
50 | * @return void
51 | */
52 | protected function mapWebRoutes()
53 | {
54 | Route::middleware('web')
55 | ->namespace($this->namespace)
56 | ->group(base_path('routes/web.php'));
57 | }
58 |
59 | /**
60 | * Define the "api" routes for the application.
61 | *
62 | * These routes are typically stateless.
63 | *
64 | * @return void
65 | */
66 | protected function mapApiRoutes()
67 | {
68 | Route::prefix('api')
69 | ->middleware('api')
70 | ->namespace($this->namespace)
71 | ->group(base_path('routes/api.php'));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/application/app/Repositories/CategoryRepository.php:
--------------------------------------------------------------------------------
1 | model = $category;
16 | }
17 |
18 | /**
19 | * Get record by the name.
20 | *
21 | * @param string $name
22 | * @return collection
23 | */
24 | public function getByName($name)
25 | {
26 | return $this->model->where('name', $name)->first();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/application/app/Repositories/LinkRepository.php:
--------------------------------------------------------------------------------
1 | model = $link;
17 | }
18 |
19 | /**
20 | * Get number of the records
21 | *
22 | * @param int $number
23 | * @param string $sort
24 | * @param string $sortColumn
25 | * @return Paginate
26 | */
27 | public function page($number = 10, $sort = 'desc', $sortColumn = 'created_at')
28 | {
29 | $this->model = $this->checkAuthScope();
30 |
31 | return $this->model->orderBy($sortColumn, $sort)->paginate($number);
32 | }
33 |
34 | /**
35 | * Get the article record without draft scope.
36 | *
37 | * @param int $id
38 | * @return mixed
39 | */
40 | public function getById($id)
41 | {
42 | return $this->model->withoutGlobalScope(StatusScope::class)->findOrFail($id);
43 | }
44 |
45 | /**
46 | * Update the article record without draft scope.
47 | *
48 | * @param int $id
49 | * @param array $input
50 | * @return boolean
51 | */
52 | public function update($id, $input)
53 | {
54 | $this->model = $this->model->withoutGlobalScope(StatusScope::class)->findOrFail($id);
55 |
56 | return $this->save($this->model, $input);
57 | }
58 |
59 | /**
60 | * Check the auth and the model without global scope when user is the admin.
61 | *
62 | * @return Model
63 | */
64 | public function checkAuthScope()
65 | {
66 | if (auth()->check() && auth()->user()->is_admin) {
67 | $this->model = $this->model->withoutGlobalScope(StatusScope::class);
68 | }
69 |
70 | return $this->model;
71 | }
72 |
73 | /**
74 | * Delete the draft article.
75 | *
76 | * @param int $id
77 | * @return boolean
78 | */
79 | public function destroy($id)
80 | {
81 | return $this->getById($id)->delete();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/application/app/Repositories/TagRepository.php:
--------------------------------------------------------------------------------
1 | model = $tag;
16 | }
17 |
18 | /**
19 | * Get record by the name.
20 | *
21 | * @param string $name
22 | * @return collection
23 | */
24 | public function getByName($name)
25 | {
26 | return $this->model->where('tag', $name)->first();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/application/app/Repositories/VisitorRepository.php:
--------------------------------------------------------------------------------
1 | model = $visitor->with('article');
30 |
31 | $this->ip = $ip;
32 | }
33 |
34 | /**
35 | * Update or create the record of visitors table
36 | *
37 | * @param $article_id
38 | */
39 | public function log($article_id)
40 | {
41 | $ip = $this->ip->get();
42 |
43 | if ($this->hasArticleIp($article_id, $ip)) {
44 |
45 | $this->model->where('article_id', $article_id)
46 | ->where('ip', $ip)
47 | ->increment('clicks');
48 |
49 | } else {
50 | $data = [
51 | 'ip' => $ip,
52 | 'article_id' => $article_id,
53 | 'clicks' => 1
54 | ];
55 | $this->model->firstOrCreate( $data );
56 | }
57 | }
58 |
59 | /**
60 | * Check the record by article id and ip if it exists.
61 | *
62 | * @param $article_id
63 | * @param $ip
64 | * @return bool
65 | */
66 | public function hasArticleIp($article_id, $ip)
67 | {
68 | return $this->model
69 | ->where('article_id', $article_id)
70 | ->where('ip', $ip)
71 | ->count() ? true : false;
72 | }
73 |
74 | /**
75 | * Get all the clicks.
76 | *
77 | * @return int
78 | */
79 | public function getAllClicks()
80 | {
81 | return $this->model->sum('clicks');
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/application/app/Scopes/DraftScope.php:
--------------------------------------------------------------------------------
1 | where('is_draft', 0);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/application/app/Scopes/StatusScope.php:
--------------------------------------------------------------------------------
1 | where('status', 1);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/application/app/Tag.php:
--------------------------------------------------------------------------------
1 | morphedByMany(Article::class, 'taggable');
36 | }
37 |
38 | /**
39 | * Get all of the discussions that are assigned this tag.
40 | *
41 | * @return \Illuminate\Database\Eloquent\Relations\MorpheBymany
42 | */
43 | public function discussions()
44 | {
45 | return $this->morphedByMany(Discussion::class, 'taggable');
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/application/app/Tools/IP.php:
--------------------------------------------------------------------------------
1 | request = $request;
21 | }
22 |
23 | /**
24 | * Get the client ip.
25 | *
26 | * @return mixed|string
27 | */
28 | public function get()
29 | {
30 | $ip = $this->request->getClientIp();
31 |
32 | if($ip == '::1') {
33 | $ip = '127.0.0.1';
34 | }
35 |
36 | return $ip;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/application/app/Tools/Markdowner.php:
--------------------------------------------------------------------------------
1 | htmlConverter = new HtmlConverter();
26 |
27 | $this->markdownConverter = new Parsedown();
28 | }
29 |
30 | /**
31 | * Convert Markdown To Html.
32 | *
33 | * @param $markdown
34 | * @return string
35 | */
36 | public function convertMarkdownToHtml($markdown)
37 | {
38 | return $this->markdownConverter
39 | ->setBreaksEnabled(true)
40 | ->text($markdown);
41 | }
42 |
43 | /**
44 | * Convert Html To Markdown.
45 | *
46 | * @param $html
47 | * @return string
48 | */
49 | public function convertHtmlToMarkdown($html)
50 | {
51 | return $this->htmlConverter->convert($html);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/application/app/Tools/Mention.php:
--------------------------------------------------------------------------------
1 | content, $atlist_tmp);
25 |
26 | $usernames = [];
27 |
28 | foreach ($atlist_tmp[2] as $k=>$v) {
29 | if ($atlist_tmp[1][$k] || strlen($v) >25) {
30 | continue;
31 | }
32 | $usernames[] = $v;
33 | }
34 | return array_unique($usernames);
35 | }
36 |
37 | /**
38 | * Replace the `@{user}` by the user link
39 | */
40 | public function replace()
41 | {
42 | $this->content_parsed = $this->content;
43 |
44 | foreach ($this->users as $user) {
45 | $search = '@' . $user->name;
46 |
47 | $place = '[' . $search . '](' . url('user', $user->name) . ')';
48 |
49 | $this->content_parsed = str_replace($search, $place, $this->content_parsed);
50 | }
51 | }
52 |
53 | /**
54 | * Parse the `@` mention user in content.
55 | *
56 | * @param string $content
57 | * @return string
58 | */
59 | public function parse($content)
60 | {
61 | $this->content = $content;
62 |
63 | $this->usernames = $this->getMentionedUsername();
64 |
65 | count($this->usernames) > 0 && $this->users = User::whereIn('name', $this->usernames)->get();
66 |
67 | $this->replace();
68 |
69 | return $this->content_parsed;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/application/app/Traits/FollowTrait.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This source file is subject to the MIT license that is bundled
8 | * with this source code in the file LICENSE.
9 | */
10 | namespace App\Traits;
11 |
12 | /**
13 | * Trait FollowTrait.
14 | */
15 | trait FollowTrait
16 | {
17 | /**
18 | * Follow a user or users.
19 | *
20 | * @param int|array $user
21 | *
22 | * @return int
23 | */
24 | public function follow($user)
25 | {
26 | return $this->followings()->sync((array)$user, false);
27 | }
28 |
29 | /**
30 | * Unfollow a user or users.
31 | *
32 | * @param int|array $user
33 | *
34 | * @return int
35 | */
36 | public function unfollow($user)
37 | {
38 | return $this->followings()->detach((array)$user);
39 | }
40 |
41 | /**
42 | * Check if user is following given user.
43 | *
44 | * @param $user
45 | *
46 | * @return bool
47 | */
48 | public function isFollowing($user)
49 | {
50 | return $this->followings->contains($user);
51 | }
52 |
53 | /**
54 | * Check if user is followed by given user.
55 | *
56 | * @param $user
57 | *
58 | * @return bool
59 | */
60 | public function isFollowedBy($user)
61 | {
62 | return $this->followers->contains($user);
63 | }
64 |
65 | /**
66 | * Return user followers.
67 | *
68 | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
69 | */
70 | public function followers()
71 | {
72 | return $this->belongsToMany(__CLASS__, 'followers', 'follow_id', 'user_id')->withTimestamps();
73 | }
74 |
75 | /**
76 | * Return user following users.
77 | *
78 | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
79 | */
80 | public function followings()
81 | {
82 | return $this->belongsToMany(__CLASS__, 'followers', 'user_id', 'follow_id')->withTimestamps();
83 | }
84 | }
--------------------------------------------------------------------------------
/application/app/Transformers/ArticleTransformer.php:
--------------------------------------------------------------------------------
1 | $article->id,
19 | 'title' => $article->title,
20 | 'subtitle' => $article->subtitle,
21 | 'user' => $article->user,
22 | 'slug' => $article->slug,
23 | 'content' => $article->content['raw'],
24 | 'page_image' => $article->page_image,
25 | 'meta_description' => $article->meta_description,
26 | 'is_original' => $article->is_original,
27 | 'is_draft' => $article->is_draft,
28 | 'visitors' => $article->view_count,
29 | 'published_at' => $article->published_at->diffForHumans(),
30 | 'published_time' => $article->published_at->toDateTimeString(),
31 | ];
32 | }
33 |
34 | /**
35 | * Include Category
36 | *
37 | * @param Article $article
38 | * @return \League\Fractal\Resource\Collection
39 | */
40 | public function includeCategory(Article $article)
41 | {
42 | $category = $article->category;
43 |
44 | return $this->item($category, new CategoryTransformer);
45 | }
46 |
47 | /**
48 | * Include Tags
49 | *
50 | * @param Article $article
51 | * @return \League\Fractal\Resource\Collection
52 | */
53 | public function includeTags(Article $article)
54 | {
55 | $tags = $article->tags;
56 |
57 | return $this->collection($tags, new TagTransformer);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/application/app/Transformers/CategoryTransformer.php:
--------------------------------------------------------------------------------
1 | $category->id,
14 | 'name' => $category->name,
15 | 'path' => $category->path,
16 | 'description' => $category->description,
17 | 'status' => $category->status,
18 | 'created_at' => $category->created_at->toDateTimeString(),
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/application/app/Transformers/CommentTransformer.php:
--------------------------------------------------------------------------------
1 | content);
16 |
17 | return [
18 | 'id' => $comment->id,
19 | 'user_id' => $comment->user_id,
20 | 'username' => isset($comment->user) ? $comment->user->name : 'Null',
21 | 'avatar' => isset($comment->user) ? $comment->user->avatar : config('blog.default_avatar'),
22 | 'commentable' => isset($comment->commentable) ? $comment->commentable->title : 'Be Forbidden!',
23 | 'type' => $comment->commentable_type,
24 | 'content_raw' => $content->raw,
25 | 'created_at' => $comment->created_at->diffForHumans(),
26 | 'is_voted' => auth()->guard('api')->id() ? $comment->isVotedBy(auth()->guard('api')->id()) : false,
27 | 'is_up_voted' => auth()->guard('api')->id() ? auth()->guard('api')->user()->hasUpVoted($comment) : false,
28 | 'is_down_voted' => auth()->guard('api')->id() ? auth()->guard('api')->user()->hasDownVoted($comment) : false,
29 | 'vote_count' => $comment->countUpVoters(),
30 | ];
31 | }
32 |
33 | /**
34 | * Include User
35 | *
36 | * @param Comment $comment
37 | * @return \League\Fractal\Resource\Collection
38 | */
39 | public function includeUser(Comment $comment)
40 | {
41 | $user = $comment->user;
42 |
43 | return $this->item($user, new UserTransformer);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/application/app/Transformers/EmptyTransformer.php:
--------------------------------------------------------------------------------
1 | $link->id,
14 | 'name' => $link->name,
15 | 'image' => $link->image,
16 | 'link' => $link->link,
17 | 'status' => (bool) $link->status,
18 | 'created_at' => $link->created_at->toDateTimeString(),
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/application/app/Transformers/TagTransformer.php:
--------------------------------------------------------------------------------
1 | $tag->id,
14 | 'tag' => $tag->tag,
15 | 'title' => $tag->title,
16 | 'meta_description' => $tag->meta_description,
17 | 'status' => $tag->status,
18 | 'created_at' => $tag->created_at->toDateTimeString(),
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/application/app/Transformers/UserTransformer.php:
--------------------------------------------------------------------------------
1 | $user->id,
14 | 'avatar' => $user->avatar,
15 | 'name' => $user->name,
16 | 'status' => $user->status,
17 | 'email' => $user->email,
18 | 'nickname' => $user->nickname,
19 | 'is_admin' => $user->is_admin,
20 | 'github_name' => $user->github_name,
21 | 'website' => $user->website,
22 | 'description' => $user->description,
23 | 'created_at' => $user->created_at->toDateTimeString(),
24 | ];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/application/app/Transformers/VisitorTransformer.php:
--------------------------------------------------------------------------------
1 | $visitor->id,
14 | 'article' => [ 'title' => isset($visitor->article) ? $visitor->article->title : 'null' ],
15 | 'ip' => $visitor->ip,
16 | 'country' => $visitor->country,
17 | 'clicks' => $visitor->clicks,
18 | 'created_at' => $visitor->created_at->toDateTimeString(),
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/application/app/Visitor.php:
--------------------------------------------------------------------------------
1 | belongsTo(Article::class);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/application/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
32 |
33 | $status = $kernel->handle(
34 | $input = new Symfony\Component\Console\Input\ArgvInput,
35 | new Symfony\Component\Console\Output\ConsoleOutput
36 | );
37 |
38 | /*
39 | |--------------------------------------------------------------------------
40 | | Shutdown The Application
41 | |--------------------------------------------------------------------------
42 | |
43 | | Once Artisan has finished running. We will fire off the shutdown events
44 | | so that any final work may be done by the application before we shut
45 | | down the process. This is the last thing to happen to the request.
46 | |
47 | */
48 |
49 | $kernel->terminate($input, $status);
50 |
51 | exit($status);
52 |
--------------------------------------------------------------------------------
/application/bootstrap/app.php:
--------------------------------------------------------------------------------
1 | singleton(
30 | Illuminate\Contracts\Http\Kernel::class,
31 | App\Http\Kernel::class
32 | );
33 |
34 | $app->singleton(
35 | Illuminate\Contracts\Console\Kernel::class,
36 | App\Console\Kernel::class
37 | );
38 |
39 | $app->singleton(
40 | Illuminate\Contracts\Debug\ExceptionHandler::class,
41 | App\Exceptions\Handler::class
42 | );
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Return The Application
47 | |--------------------------------------------------------------------------
48 | |
49 | | This script returns the application instance. The instance is given to
50 | | the calling script so we can separate the building of the instances
51 | | from the actual running of the application and sending responses.
52 | |
53 | */
54 |
55 | return $app;
56 |
--------------------------------------------------------------------------------
/application/bootstrap/autoload.php:
--------------------------------------------------------------------------------
1 | env('BROADCAST_DRIVER', 'null'),
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Broadcast Connections
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may define all of the broadcast connections that will be used
26 | | to broadcast events to other systems or over websockets. Samples of
27 | | each available type of connection are provided inside this array.
28 | |
29 | */
30 |
31 | 'connections' => [
32 |
33 | 'pusher' => [
34 | 'driver' => 'pusher',
35 | 'key' => env('PUSHER_APP_KEY'),
36 | 'secret' => env('PUSHER_APP_SECRET'),
37 | 'app_id' => env('PUSHER_APP_ID'),
38 | 'options' => [
39 | //
40 | ],
41 | ],
42 |
43 | 'redis' => [
44 | 'driver' => 'redis',
45 | 'connection' => 'default',
46 | ],
47 |
48 | 'log' => [
49 | 'driver' => 'log',
50 | ],
51 |
52 | 'null' => [
53 | 'driver' => 'null',
54 | ],
55 |
56 | ],
57 |
58 | ];
--------------------------------------------------------------------------------
/application/config/compile.php:
--------------------------------------------------------------------------------
1 | [
17 | //
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled File Providers
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may list service providers which define a "compiles" function
26 | | that returns additional files that should be compiled, providing an
27 | | easy way to get common files from any packages you are utilizing.
28 | |
29 | */
30 |
31 | 'providers' => [
32 | //
33 | ],
34 |
35 | ];
36 |
--------------------------------------------------------------------------------
/application/config/image.php:
--------------------------------------------------------------------------------
1 | 'gd'
19 |
20 | );
21 |
--------------------------------------------------------------------------------
/application/config/services.php:
--------------------------------------------------------------------------------
1 | [
18 | 'domain' => env('MAILGUN_DOMAIN'),
19 | 'secret' => env('MAILGUN_SECRET'),
20 | ],
21 |
22 | 'ses' => [
23 | 'key' => env('SES_KEY'),
24 | 'secret' => env('SES_SECRET'),
25 | 'region' => 'us-east-1',
26 | ],
27 |
28 | 'sparkpost' => [
29 | 'secret' => env('SPARKPOST_SECRET'),
30 | ],
31 |
32 | 'stripe' => [
33 | 'model' => App\User::class,
34 | 'key' => env('STRIPE_KEY'),
35 | 'secret' => env('STRIPE_SECRET'),
36 | ],
37 |
38 | // Third-party login configuration
39 | 'github' => [
40 | 'client_id' => env('GITHUB_CLIENT_ID'),
41 | 'client_secret' => env('GITHUB_CLIENT_SECRET'),
42 | 'redirect' => env('GITHUB_REDIRECT'),
43 | ],
44 |
45 | // Translation
46 | 'youdao' => [
47 | 'appKey' => env('YOUDAO_APP_KEY'),
48 | 'appSecret' => env('YOUDAO_APP_SECRET'),
49 | ],
50 |
51 | ];
52 |
--------------------------------------------------------------------------------
/application/config/view.php:
--------------------------------------------------------------------------------
1 | [
17 | realpath(base_path('resources/views')),
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Compiled View Path
23 | |--------------------------------------------------------------------------
24 | |
25 | | This option determines where all the compiled Blade templates will be
26 | | stored for your application. Typically, this is within the storage
27 | | directory. However, as usual, you are free to change this value.
28 | |
29 | */
30 |
31 | 'compiled' => realpath(storage_path('framework/views')),
32 |
33 | ];
34 |
--------------------------------------------------------------------------------
/application/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 |
--------------------------------------------------------------------------------
/application/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/application/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name')->unique();
19 | $table->string('nickname')->nullable();
20 | $table->text('avatar')->nullable();
21 | $table->string('email')->unique();
22 | $table->string('confirm_code', 64)->unique()->nullable();
23 | $table->tinyInteger('status')->default(false);
24 | $table->boolean('is_admin')->default(false);
25 | $table->string('password');
26 | $table->string('github_id')->nullable();
27 | $table->string('github_name')->nullable();
28 | $table->string('github_url')->nullable();
29 | $table->string('weibo_name')->nullable();
30 | $table->string('weibo_link')->nullable();
31 | $table->string('website')->nullable();
32 | $table->string('description')->nullable();
33 | $table->enum('email_notify_enabled', ['yes', 'no'])->default('yes')->index();
34 | $table->rememberToken();
35 | $table->timestamps();
36 | $table->softDeletes();
37 | });
38 | }
39 |
40 | /**
41 | * Reverse the migrations.
42 | *
43 | * @return void
44 | */
45 | public function down()
46 | {
47 | Schema::drop('users');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/application/database/migrations/2014_10_12_100000_create_password_resets_table.php:
--------------------------------------------------------------------------------
1 | string('email')->index();
18 | $table->string('token')->index();
19 | $table->timestamp('created_at')->nullable();
20 | });
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | *
26 | * @return void
27 | */
28 | public function down()
29 | {
30 | Schema::drop('password_resets');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_02_065857_create_articles_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->integer('category_id')->unsigned();
19 | $table->integer('user_id')->unsigned();
20 | $table->integer('last_user_id')->unsigned();
21 | $table->string('slug')->unique();
22 | $table->string('title');
23 | $table->string('subtitle');
24 | // $table->json('content');
25 | $table->text('content');
26 | $table->string('page_image')->nullable();
27 | $table->string('meta_description')->nullable();
28 | $table->boolean('is_original')->default(false);
29 | $table->boolean('is_draft')->default(false);
30 | $table->integer('view_count')->unsigned()->default(0)->index();
31 | $table->timestamp('published_at')->nullable();
32 | $table->timestamps();
33 | $table->softDeletes();
34 | });
35 | }
36 |
37 | /**
38 | * Reverse the migrations.
39 | *
40 | * @return void
41 | */
42 | public function down()
43 | {
44 | Schema::dropIfExists('articles');
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_02_065920_create_tags_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('tag')->unique();
19 | $table->string('title');
20 | $table->string('meta_description');
21 | $table->timestamps();
22 | $table->softDeletes();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | *
29 | * @return void
30 | */
31 | public function down()
32 | {
33 | Schema::dropIfExists('tags');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_02_065952_create_visitors_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->integer('article_id')->unsigned();
19 | $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
20 | $table->string('ip', 32);
21 | $table->string('country')->nullable();
22 | $table->integer('clicks')->unsigned()->default(1);
23 | $table->timestamps();
24 | });
25 | }
26 |
27 | /**
28 | * Reverse the migrations.
29 | *
30 | * @return void
31 | */
32 | public function down()
33 | {
34 | Schema::dropIfExists('visitors');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_02_070119_create_categories_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->tinyInteger('parent_id')->unsigned()->default(0);
19 | $table->string('name');
20 | $table->string('path');
21 | $table->string('description')->nullable();
22 | $table->string('image_url')->nullable();
23 | $table->timestamps();
24 | });
25 | }
26 |
27 | /**
28 | * Reverse the migrations.
29 | *
30 | * @return void
31 | */
32 | public function down()
33 | {
34 | Schema::dropIfExists('categories');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_02_070132_create_discussions_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->integer('user_id')->unsigned();
19 | $table->integer('last_user_id')->unsigned();
20 | $table->string('title');
21 | // $table->json('content');
22 | $table->text('content');
23 | $table->tinyInteger('status')->default(false);
24 | $table->timestamps();
25 | $table->softDeletes();
26 | });
27 | }
28 |
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('discussions');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_02_070151_create_comments_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->integer('user_id')->unsigned();
19 | $table->integer('commentable_id')->unsigned();
20 | $table->char('commentable_type');
21 | // $table->json('content');
22 | $table->text('content');
23 | $table->timestamps();
24 | $table->softDeletes();
25 | });
26 | }
27 |
28 | /**
29 | * Reverse the migrations.
30 | *
31 | * @return void
32 | */
33 | public function down()
34 | {
35 | Schema::dropIfExists('comments');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_09_13_022056_create_links_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->string('name')->index();
19 | $table->string('link')->index();
20 | $table->text('image')->nullable();
21 | $table->boolean('status')->default(true);
22 | $table->timestamps();
23 | $table->softDeletes();
24 | });
25 | }
26 |
27 | /**
28 | * Reverse the migrations.
29 | *
30 | * @return void
31 | */
32 | public function down()
33 | {
34 | Schema::dropIfExists('links');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_11_11_163610_create_taggables_table.php:
--------------------------------------------------------------------------------
1 | integer('tag_id')->unsigned()->index();
18 | $table->integer('taggable_id')->unsigned()->index();
19 | $table->string('taggable_type')->index();
20 | });
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | *
26 | * @return void
27 | */
28 | public function down()
29 | {
30 | Schema::dropIfExists('taggables');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_12_11_153312_create_followers_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->unsignedInteger('user_id');
19 | $table->unsignedInteger('follow_id');
20 | $table->timestamps();
21 | });
22 | }
23 |
24 | /**
25 | * Reverse the migrations.
26 | *
27 | * @return void
28 | */
29 | public function down()
30 | {
31 | Schema::dropIfExists('followers');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_12_12_171655_create_notifications_table.php:
--------------------------------------------------------------------------------
1 | uuid('id')->primary();
17 | $table->string('type');
18 | $table->morphs('notifiable');
19 | $table->text('data');
20 | $table->timestamp('read_at')->nullable();
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::dropIfExists('notifications');
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/application/database/migrations/2016_12_12_205419_create_failed_jobs_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
18 | $table->text('connection');
19 | $table->text('queue');
20 | $table->longText('payload');
21 | $table->longText('exception');
22 | $table->timestamp('failed_at')->useCurrent();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | *
29 | * @return void
30 | */
31 | public function down()
32 | {
33 | Schema::dropIfExists('failed_jobs');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/application/database/migrations/2017_04_14_013622_create_votes_table.php:
--------------------------------------------------------------------------------
1 | unsignedInteger('user_id');
17 | $table->unsignedInteger('votable_id');
18 | $table->string('votable_type')->index();
19 | $table->enum('type', ['up_vote', 'down_vote'])->default('up_vote');
20 |
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | *
28 | * @return void
29 | */
30 | public function down()
31 | {
32 | Schema::drop('votes');
33 | }
34 | }
--------------------------------------------------------------------------------
/application/database/seeds/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/application/database/seeds/ArticlesTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/application/database/seeds/CategoriesTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/application/database/seeds/CommentsTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/application/database/seeds/DatabaseSeeder.php:
--------------------------------------------------------------------------------
1 | call(UsersTableSeeder::class);
15 | $this->call(CategoriesTableSeeder::class);
16 | $this->call(ArticlesTableSeeder::class);
17 | $this->call(DiscussionsTableSeeder::class);
18 | $this->call(CommentsTableSeeder::class);
19 | $this->call(TagsTableSeeder::class);
20 | $this->call(LinksTableSeeder::class);
21 | $this->call(VisitorsTableSeeder::class);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/application/database/seeds/DiscussionsTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/application/database/seeds/LinksTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/application/database/seeds/TagsTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/application/database/seeds/UsersTableSeeder.php:
--------------------------------------------------------------------------------
1 | 'admin',
19 | 'email' => 'admin@pigjian.com',
20 | 'password' => Hash::make('admin'),
21 | 'status' => true,
22 | 'is_admin' => true,
23 | 'confirm_code' => str_random(64),
24 | 'created_at' => Carbon::now(),
25 | 'updated_at' => Carbon::now()
26 | ]
27 | ];
28 |
29 | DB::table('users')->insert($users);
30 |
31 | factory(User::class, 10)->create();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/application/database/seeds/VisitorsTableSeeder.php:
--------------------------------------------------------------------------------
1 | create();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/application/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "npm run development",
5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
7 | "watch-poll": "npm run watch -- --watch-poll",
8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
9 | "prod": "npm run production",
10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
11 | },
12 | "devDependencies": {
13 | "axios": "^0.15.2",
14 | "babel-preset-es2015": "^6.24.1",
15 | "babel-preset-stage-2": "^6.24.1",
16 | "bootstrap-sass": "^3.3.7",
17 | "chart.js": "^2.4.0",
18 | "cropperjs": "^1.0.0-rc.1",
19 | "cross-env": "^5.0.5",
20 | "emojione": "^2.2.7",
21 | "fine-uploader": "^5.14.2-rc1",
22 | "ionicons": "^2.0.1",
23 | "jquery": "^3.1.0",
24 | "laravel-mix": "^1.4.0",
25 | "lodash": "^4.16.2",
26 | "marked": "^0.3.6",
27 | "path-to-regexp": "^1.7.0",
28 | "simplemde": "^1.11.2",
29 | "social-share.js": "^1.0.15",
30 | "sweetalert": "^1.1.3",
31 | "toastr": "^2.1.2",
32 | "v-textcomplete": "^0.1.2",
33 | "vue": "^2.1.6",
34 | "vue-datepicker": "^1.3.0",
35 | "vue-i18n": "v6.0.0-alpha.5",
36 | "vue-multiselect": "^2.0.0-beta.15",
37 | "vue-router": "^2.1.1",
38 | "vuex": "^2.1.1"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/application/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 | {{ title }}
8 |
';
12 | });
13 |
14 | swal({
15 | title: "Error Text!",
16 | type: 'error',
17 | text: content,
18 | html: true
19 | });
20 | }
21 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/config/menu.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | label: 'sidebar.dashboard',
4 | icon : 'ion-ios-speedometer',
5 | uri : '/dashboard/home'
6 | },
7 | {
8 | label: 'sidebar.user',
9 | icon : 'ion-person-stalker',
10 | uri : '/dashboard/users'
11 | },
12 | {
13 | label: 'sidebar.article',
14 | icon : 'ion-ios-book',
15 | uri : '/dashboard/articles'
16 | },
17 | {
18 | label: 'sidebar.discussion',
19 | icon : 'ion-help-circled',
20 | uri : '/dashboard/discussions'
21 | },
22 | {
23 | label: 'sidebar.comment',
24 | icon : 'ion-chatbubble-working',
25 | uri : '/dashboard/comments'
26 | },
27 | {
28 | label: 'sidebar.file',
29 | icon : 'ion-ios-folder',
30 | uri : '/dashboard/files'
31 | },
32 | {
33 | label: 'sidebar.tag',
34 | icon : 'ion-ios-pricetags',
35 | uri : '/dashboard/tags'
36 | },
37 | {
38 | label: 'sidebar.category',
39 | icon : 'ion-ios-list',
40 | uri : '/dashboard/categories'
41 | },
42 | {
43 | label: 'sidebar.link',
44 | icon : 'ion-ios-world',
45 | uri : '/dashboard/links'
46 | },
47 | {
48 | label: 'sidebar.visitor',
49 | icon : 'ion-chatbubble-working',
50 | uri : '/dashboard/visitors'
51 | },
52 | {
53 | label: 'sidebar.system',
54 | icon : 'ion-gear-b',
55 | uri : '/dashboard/system'
56 | }
57 | ]
--------------------------------------------------------------------------------
/application/resources/assets/js/config/toastr.js:
--------------------------------------------------------------------------------
1 | export default {
2 | positionClass: "toast-bottom-right",
3 | showDuration: "300",
4 | hideDuration: "1000",
5 | timeOut: "5000",
6 | extendedTimeOut: "1000",
7 | showEasing: "swing",
8 | hideEasing: "linear",
9 | showMethod: "fadeIn",
10 | hideMethod: "fadeOut"
11 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/home.js:
--------------------------------------------------------------------------------
1 | window.$ = window.jQuery = require('jquery');
2 | window.swal = require('sweetalert');
3 | window.Vue = require('vue');
4 |
5 | import VueI18n from 'vue-i18n';
6 | import locales from 'lang';
7 | import httpPlugin from 'plugins/http';
8 |
9 | require('bootstrap-sass');
10 | require('social-share.js/dist/js/social-share.min.js');
11 | require('vendor/select2.min.js');
12 | window.marked = require('marked');
13 | window.hljs = require('vendor/highlight.min.js');
14 | window.toastr = require('toastr/build/toastr.min.js');
15 |
16 | Vue.use(VueI18n);
17 | Vue.use(httpPlugin);
18 |
19 | Vue.config.lang = window.Language;
20 |
21 | const i18n = new VueI18n({
22 | locale: Vue.config.lang,
23 | messages: locales
24 | })
25 |
26 | Vue.component('comment', require('components/Comment.vue'));
27 |
28 | Vue.component('parse', require('components/Parse.vue'));
29 |
30 | Vue.component('parse-textarea', require('components/Textarea.vue'));
31 |
32 | Vue.component('avatar', require('components/AvatarUpload.vue'));
33 |
34 | new Vue({
35 | i18n: i18n,
36 | }).$mount('#app');
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/en/index.js:
--------------------------------------------------------------------------------
1 | import sidebar from './sidebar'
2 | import page from './page'
3 | import table from './table'
4 | import form from './form'
5 |
6 | export default {
7 | sidebar,
8 | page,
9 | table,
10 | form
11 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/en/page.js:
--------------------------------------------------------------------------------
1 | export default {
2 | users: 'Users',
3 | visitors: 'Visitors',
4 | articles: 'Articles',
5 | comments: 'Comments',
6 | discussions: 'Discussions',
7 | files: 'Files',
8 | tags: 'Tags',
9 | categories: 'Categories',
10 | links: 'Links',
11 | systems: 'Systems',
12 | user_num: 'Users',
13 | view_num: 'Views',
14 | article_num: 'Articles',
15 | comment_num: 'Comments',
16 | all: 'All',
17 | admin: 'Admin',
18 | create: 'Create',
19 | system: 'System',
20 | database: 'Database',
21 | key: 'Setting',
22 | value: 'Value',
23 | server: 'Web Server',
24 | domain: 'Domain',
25 | version: 'Version',
26 | extension: 'Extension',
27 | driver: 'Driver',
28 | nothing: 'No Content'
29 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/en/sidebar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | dashboard: 'Dashboard',
3 | user: 'Users',
4 | article: 'Articles',
5 | discussion: 'Discussion',
6 | comment: 'Comments',
7 | tag: 'Tags',
8 | file: 'Files',
9 | category: 'Categories',
10 | link: 'Links',
11 | visitor: 'Visitors',
12 | system: 'Systems'
13 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/en/table.js:
--------------------------------------------------------------------------------
1 | export default {
2 | id: 'ID',
3 | avatar: 'Avatar',
4 | username: 'User Name',
5 | email: 'E-Mail Address',
6 | status: 'Status',
7 | title: 'Title',
8 | subtitle: 'Sub Title',
9 | created_at: 'Created At',
10 | published_at: 'Published At',
11 | comment_type: 'Commentable Type',
12 | comment_title: 'Commentable Title',
13 | tag: 'Tag',
14 | meta_description: 'Meta Description',
15 | name: 'Name',
16 | type: 'Type',
17 | date: 'Date Time',
18 | size: 'Size',
19 | action: 'Actions',
20 | path: 'Path',
21 | image: 'Image',
22 | link: 'Link',
23 | enabled: 'Enabled',
24 | article_title: 'Article Title',
25 | click_num: 'Clicks Num',
26 | ip: 'IP',
27 | new_folder: 'New Folder',
28 | upload: 'Uplaod'
29 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/index.js:
--------------------------------------------------------------------------------
1 | import en from './en'
2 | import zh_cn from './zh_cn'
3 |
4 | export default {
5 | en,
6 | zh_cn
7 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/zh_cn/form.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'name': '用户名',
3 | 'email': '邮箱',
4 | 'password': '密码',
5 | 'confirm_password': '确认密码',
6 | 'category': '分类',
7 | 'select_option': '选择选项',
8 | 'title': '标题',
9 | 'subtitle': '副标题',
10 | 'page_image': '页面图像',
11 | 'content': '内容',
12 | 'content_notice': '请输入内容',
13 | 'tag': '标签',
14 | 'select_tag': '选择标签',
15 | 'select_category': '选择分类',
16 | 'meta_description': '主要描述',
17 | 'datetime': '日期时间',
18 | 'is_draft': '是否草稿?',
19 | 'is_original': '是否原创?',
20 | 'status': '状态',
21 | 'discussions': '讨论',
22 | 'articles': '文章',
23 | 'folder_name': '文件夹名',
24 | 'file': '文件',
25 | 'file_name': '文件名',
26 | 'cancel': '取消',
27 | 'ok': '确认',
28 | 'category_name': '分类名字',
29 | 'description': '描述',
30 | 'path': '路径',
31 | 'link_name': '链接名',
32 | 'link': '链接',
33 | 'image': '图像',
34 | 'is_enable': '是否开启',
35 | 'yes': '是',
36 | 'no': '否',
37 | 'create_user': '创建用户',
38 | 'edit_user': '修改用户',
39 | 'back': '返回',
40 | 'nickname': '昵称',
41 | 'website': '网站地址',
42 | 'create_article': '创建文章',
43 | 'edit_article': '修改文章',
44 | 'create_discussion': '创建讨论',
45 | 'edit_discussion': '修改讨论',
46 | 'edit_comment': '修改评论',
47 | 'submit_comment': '发布评论',
48 | 'create_tag': '创建标签',
49 | 'edit_tag': '修改标签',
50 | 'create_folder': '创建文件夹',
51 | 'upload_file': '上传文件',
52 | 'create_category': '创建分类',
53 | 'edit_category': '修改分类',
54 | 'category_description': '请输入分类描述',
55 | 'create_link': '创建友链',
56 | 'edit_link': '修改友链',
57 | 'create': '创建',
58 | 'edit': '修改',
59 | 'crop_avatar': '裁剪头像',
60 | 'modify_avatar': '修改头像',
61 | 'content_placeholder': '请输入{type}内容。',
62 | 'article': '文章',
63 | 'discussion': '讨论',
64 | 'comment': '评论',
65 | 'published_at': '发布时间?',
66 |
67 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/zh_cn/index.js:
--------------------------------------------------------------------------------
1 | import sidebar from './sidebar'
2 | import page from './page'
3 | import table from './table'
4 | import form from './form'
5 |
6 | export default {
7 | sidebar,
8 | page,
9 | table,
10 | form
11 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/zh_cn/page.js:
--------------------------------------------------------------------------------
1 | export default {
2 | users: '用户列表',
3 | visitors: '访问列表',
4 | articles: '文章列表',
5 | comments: '评论列表',
6 | discussions: '讨论列表',
7 | files: '文件列表',
8 | tags: '标签列表',
9 | categories: '分类列表',
10 | links: '友链列表',
11 | systems: '系统设置',
12 | user_num: '用户数',
13 | view_num: '访问数',
14 | article_num: '文章数',
15 | comment_num: '评论数',
16 | all: '全部',
17 | admin: '管理员',
18 | create: '创建',
19 | system: '系统',
20 | database: '数据库',
21 | key: '设置',
22 | value: '值',
23 | server: '网站服务器',
24 | domain: '域名',
25 | version: '版本',
26 | extension: '扩展',
27 | driver: '驱动',
28 | nothing: 'No Content'
29 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/zh_cn/sidebar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | dashboard: '面板',
3 | user: '用户管理',
4 | article: '文章管理',
5 | discussion: '讨论管理',
6 | comment: '评论管理',
7 | tag: '标签管理',
8 | file: '文件管理',
9 | category: '分类管理',
10 | link: '友链管理',
11 | visitor: '访问列表',
12 | system: '系统配置'
13 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/lang/zh_cn/table.js:
--------------------------------------------------------------------------------
1 | export default {
2 | id: 'ID',
3 | avatar: '头像',
4 | username: '用户名',
5 | email: '邮箱地址',
6 | status: '状态',
7 | title: '标题',
8 | subtitle: '副标题',
9 | created_at: '创建时间',
10 | published_at: '发布时间',
11 | comment_type: '评论类型',
12 | comment_title: '评论标题',
13 | tag: '标签',
14 | meta_description: '描述',
15 | name: '名字',
16 | type: '类型',
17 | date: '日期',
18 | size: '大小',
19 | action: '操作',
20 | path: '路径',
21 | image: '图片',
22 | link: '链接',
23 | enabled: '是否启用',
24 | article_title: '文章标题',
25 | click_num: '点击次数',
26 | ip: 'IP',
27 | new_folder: '创建文件夹',
28 | upload: '上传图片'
29 | }
--------------------------------------------------------------------------------
/application/resources/assets/js/plugins/http/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { apiUrl } from 'config/base'
3 |
4 | /**
5 | * Create Axios
6 | */
7 | export const http = axios.create({
8 | baseURL: apiUrl,
9 | })
10 |
11 | /**
12 | * We'll load the axios HTTP library which allows us to easily issue requests
13 | * to our Laravel back-end. This library automatically handles sending the
14 | * CSRF token as a header based on the value of the "XSRF" token cookie.
15 | */
16 | http.defaults.headers.common = {
17 | 'X-CSRF-TOKEN': window.Laravel.csrfToken,
18 | 'X-Requested-With': 'XMLHttpRequest'
19 | };
20 |
21 | /**
22 | * Handle all error messages.
23 | */
24 | http.interceptors.response.use(function (response) {
25 | return response;
26 | }, function (error) {
27 | const { response } = error
28 |
29 | if ([401].indexOf(response.status) >= 0) {
30 | if (response.status == 401 && response.data.error.message != 'Unauthorized') {
31 | return Promise.reject(response);
32 | }
33 | window.location = '/login';
34 | }
35 |
36 | return Promise.reject(error);
37 | });
38 |
39 | export default function install(Vue) {
40 | Object.defineProperty(Vue.prototype, '$http', {
41 | get() {
42 | return http
43 | },
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/application/resources/assets/js/views/Parent.vue:
--------------------------------------------------------------------------------
1 |
2 |