├── app
├── commands
│ └── .gitkeep
├── markdown
│ ├── faq.md
│ └── news.md
├── config
│ ├── packages
│ │ ├── .gitkeep
│ │ └── artdarek
│ │ │ └── oauth-4-laravel
│ │ │ ├── .gitkeep
│ │ │ └── config.php
│ ├── compile.php
│ ├── local
│ │ ├── app.php
│ │ └── database.php
│ ├── testing
│ │ ├── cache.php
│ │ └── session.php
│ ├── services.php
│ ├── workbench.php
│ ├── view.php
│ ├── remote.php
│ ├── auth.php
│ ├── queue.php
│ ├── cache.php
│ ├── database.php
│ ├── mail.php
│ ├── session.php
│ └── app.php
├── controllers
│ ├── .gitkeep
│ ├── BaseController.php
│ ├── FeedController.php
│ ├── VotesController.php
│ ├── TagsController.php
│ ├── SearchController.php
│ ├── CommentsController.php
│ ├── PagesController.php
│ ├── SnippetsController.php
│ └── UsersController.php
├── database
│ ├── seeds
│ │ ├── .gitkeep
│ │ ├── VotesTableSeeder.php
│ │ ├── DatabaseSeeder.php
│ │ ├── SnippetsTableSeeder.php
│ │ ├── CommentsTableSeeder.php
│ │ └── UsersTableSeeder.php
│ ├── migrations
│ │ ├── .gitkeep
│ │ ├── 2014_10_31_225054_create_tags_table.php
│ │ ├── 2014_11_01_134754_create_snippets_title_fulltext_index.php
│ │ ├── 2014_10_31_225259_create_taggables_table.php
│ │ ├── 2014_10_25_122712_create_comments_table.php
│ │ ├── 2014_10_24_124915_create_snippets_table.php
│ │ ├── 2014_10_28_035857_enable_snippets_fulltext_search.php
│ │ ├── 2014_10_26_042322_create_votes_table.php
│ │ └── 2014_10_24_091019_create_users_table.php
│ └── .gitignore
├── start
│ ├── local.php
│ ├── artisan.php
│ └── global.php
├── storage
│ ├── .gitignore
│ ├── cache
│ │ └── .gitignore
│ ├── debugbar
│ │ └── .gitignore
│ ├── logs
│ │ └── .gitignore
│ ├── meta
│ │ └── .gitignore
│ ├── sessions
│ │ └── .gitignore
│ └── views
│ │ └── .gitignore
├── views
│ ├── partials
│ │ ├── paginator.blade.php
│ │ ├── search_form.blade.php
│ │ ├── tagcloud.blade.php
│ │ ├── markdown_help.blade.php
│ │ ├── comment_form.blade.php
│ │ ├── tracking.blade.php
│ │ ├── comment.blade.php
│ │ ├── statistics.blade.php
│ │ ├── snippet.blade.php
│ │ ├── snippet_form.blade.php
│ │ └── navbar.blade.php
│ ├── pages
│ │ ├── markdown.blade.php
│ │ ├── sitemap.blade.php
│ │ ├── feed.blade.php
│ │ └── home.blade.php
│ ├── snippets
│ │ ├── create.blade.php
│ │ ├── edit.blade.php
│ │ ├── index.blade.php
│ │ └── show.blade.php
│ ├── errors
│ │ ├── 404.blade.php
│ │ └── 503.blade.php
│ ├── comments
│ │ └── edit.blade.php
│ ├── search
│ │ └── index.blade.php
│ ├── users
│ │ └── show.blade.php
│ └── layouts
│ │ └── main.blade.php
├── Vimrcfu
│ ├── Facades
│ │ └── TextFacade.php
│ ├── Validation
│ │ ├── CommentValidator.php
│ │ ├── SnippetValidator.php
│ │ └── Validator.php
│ ├── Providers
│ │ ├── CoreServiceProvider.php
│ │ └── PersistenceServiceProvider.php
│ ├── Users
│ │ ├── UsersRepository.php
│ │ ├── EloquentUsersRepository.php
│ │ └── User.php
│ ├── Tags
│ │ ├── Tag.php
│ │ ├── TagsRepository.php
│ │ └── EloquentTagsRepository.php
│ ├── Comments
│ │ ├── CommentsRepository.php
│ │ ├── Comment.php
│ │ └── EloquentCommentsRepository.php
│ ├── Votes
│ │ └── Vote.php
│ ├── Exceptions
│ │ └── ValidationException.php
│ ├── Snippets
│ │ ├── SnippetsRepository.php
│ │ ├── Snippet.php
│ │ └── EloquentSnippetsRepository.php
│ └── Core
│ │ └── Text.php
├── tests
│ └── TestCase.php
├── lang
│ └── en
│ │ ├── pagination.php
│ │ ├── reminders.php
│ │ └── validation.php
├── routes.php
└── filters.php
├── public
├── packages
│ └── .gitkeep
├── robots.txt
├── favicon.ico
├── img
│ └── home_bg.png
├── apple-touch-icon.png
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.ttf
│ └── glyphicons-halflings-regular.woff
├── .htaccess
├── js
│ ├── main.js
│ ├── tagging.js
│ ├── vendor
│ │ ├── bootstrap-tagsinput.min.js.map
│ │ ├── html5shiv.js
│ │ ├── wow.min.js
│ │ └── bootstrap-tagsinput.min.js
│ └── snake.js
├── index.php
└── css
│ ├── main.css
│ └── bootstrap-theme.min.css
├── .gitattributes
├── .gitignore
├── server.php
├── config.php_cs
├── phpunit.xml
├── composer.json
├── bootstrap
├── paths.php
├── start.php
└── autoload.php
├── CONTRIBUTING.md
├── artisan
└── README.md
/app/commands/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/markdown/faq.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/markdown/news.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/config/packages/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/database/seeds/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/packages/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/app/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 |
--------------------------------------------------------------------------------
/app/start/local.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $snippets->appends(['q' => Input::get('q')])->links() }}
3 |
4 |
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/florianbeer/vimrcfu/HEAD/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/florianbeer/vimrcfu/HEAD/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/florianbeer/vimrcfu/HEAD/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/app/Vimrcfu/Facades/TextFacade.php:
--------------------------------------------------------------------------------
1 | Search
2 | {{ Form::open(['route' => 'search', 'method' => 'get']) }}
3 |
4 | {{ Form::text('q', Input::get('q'), ['class' => 'form-control', 'placeholder' => 'Search', 'tabindex' => '1']) }}
5 |
6 | {{ Form::close() }}
7 |
--------------------------------------------------------------------------------
/app/Vimrcfu/Validation/CommentValidator.php:
--------------------------------------------------------------------------------
1 | 'required|min:4'
12 | ];
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/Vimrcfu/Providers/CoreServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->bind('text', 'Vimrcfu\Core\Text');
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/app/views/pages/markdown.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.main')
2 |
3 | @section('title', $title)
4 |
5 | @section('content')
6 |
7 |
2 | @if($img == true)
3 |
8 |
9 | @else
10 |
11 | @endif
12 |
13 |
14 |
15 | {{ $snippet->created_at->diffForHumans() }}
16 | @if (Auth::check() && $snippet->user_id === Auth::user()->id)
17 | [edit]
18 | @endif
19 |
20 | by {{ $snippet->user->name }}
21 |
22 |
23 | score; ?>
24 | {{ $score }} {{ Str::plural('Point', $score) }}
25 | {{ count($snippet->comments) }} {{ Str::plural('Comment', count($snippet->comments)) }}
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/views/search/index.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.main')
2 |
3 | @section('title', 'Search Results')
4 |
5 | @section('content')
6 |
7 |
8 |
9 |
10 |
11 |
Search for {{ Input::get('q') }}
12 |
13 | {{ $total }} {{ Str::plural('Result', $total) }}
14 | @if($snippets->getLastPage() > 1)
15 | Page {{ $snippets->getCurrentPage() }} of {{ $snippets->getLastPage() }}
16 | @endif
17 |
18 |
19 |
20 |
21 | @include('partials.search_form')
22 |
23 |
24 |
25 |
26 |
27 | @include('partials.paginator')
28 |
29 |
30 |
31 |
32 |
33 | @foreach($snippets as $snippet)
34 | @include('partials.snippet', ['img' => true])
35 | @endforeach
36 |
37 |
38 |
39 | @include('partials.tagcloud', ['title' => 'Related ' . Str::plural('Tag', count($tags))])
40 |
41 |
42 |
43 |
44 |
45 | @include('partials.paginator')
46 |
47 |
48 |
49 |
50 |
51 | @stop
52 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "florianbeer/vimrcfu",
3 | "description": "Source code for the vimrcfu.com website",
4 | "keywords": ["website", "vim", "vimrc"],
5 | "homepage": "http://vimrcfu.com",
6 | "license": "CC-BY-NC-SA-4.0",
7 | "type": "project",
8 | "authors": [
9 | {
10 | "name": "Florian Beer",
11 | "email": "fb@42dev.eu",
12 | "homepage": "http://blog.no-panic.at",
13 | "role": "Developer"
14 | }
15 | ],
16 | "require": {
17 | "laravel/framework": "4.2.*",
18 | "artdarek/oauth-4-laravel": "1.0.5",
19 | "michelf/php-markdown": "1.4.*"
20 | },
21 | "require-dev": {
22 | "fzaninotto/faker": "~1.4"
23 | },
24 | "autoload": {
25 | "classmap": [
26 | "app/commands",
27 | "app/controllers",
28 | "app/database/migrations",
29 | "app/database/seeds",
30 | "app/tests/TestCase.php"
31 | ],
32 | "psr-4": {
33 | "Vimrcfu\\": "app/Vimrcfu"
34 | }
35 | },
36 | "scripts": {
37 | "post-install-cmd": [
38 | "php artisan clear-compiled",
39 | "php artisan optimize"
40 | ],
41 | "post-update-cmd": [
42 | "php artisan clear-compiled",
43 | "php artisan optimize"
44 | ],
45 | "post-create-project-cmd": [
46 | "php artisan key:generate"
47 | ]
48 | },
49 | "config": {
50 | "preferred-install": "dist"
51 | },
52 | "minimum-stability": "stable"
53 | }
54 |
--------------------------------------------------------------------------------
/app/controllers/TagsController.php:
--------------------------------------------------------------------------------
1 | repository = $repository;
19 | }
20 |
21 | /**
22 | * Incremental search for Tags,
23 | * Used in autocomplete input field.
24 | *
25 | * @return mixed
26 | */
27 | public function search($string)
28 | {
29 | return $this->repository->searchByName($string);
30 | }
31 |
32 | /**
33 | * Returns top Tags array,
34 | * Used in prefetch for autocomplete.
35 | *
36 | * @return array
37 | */
38 | public function prefetch()
39 | {
40 | return $this->repository->topTags();
41 | }
42 |
43 | /**
44 | * Displays all Snippets for a specific Tag.
45 | *
46 | * @param string $slug
47 | * @return mixed
48 | */
49 | public function show($slug)
50 | {
51 | $tag = Tag::where('slug', $slug)->first();
52 |
53 | if ( ! $tag)
54 | {
55 | App::abort(404);
56 | }
57 |
58 | $snippets = $tag->snippets()->paginate(10);
59 |
60 | return View::make('snippets.index', compact('snippets'))
61 | ->with('title', $tag->name);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/controllers/SearchController.php:
--------------------------------------------------------------------------------
1 | snippetsRepository = $snippetsRepository;
25 | $this->tagsRepository = $tagsRepository;
26 | }
27 |
28 | /**
29 | * Shows the search page or redirects to Snippets
30 | * index page in case no searchterm was entered.
31 | *
32 | * @return mixed
33 | */
34 | public function index()
35 | {
36 | $search = Input::get('q');
37 | if ( ! empty($search))
38 | {
39 | $searchresult = $this->snippetsRepository->fulltextSearch($search);
40 | $tags = $this->tagsRepository->relatedTags($search);
41 |
42 | return View::make('search.index')
43 | ->withSnippets($searchresult['items'])
44 | ->withTotal($searchresult['total'])
45 | ->withTags($tags);
46 | }
47 |
48 | return Redirect::route('snippet.index');
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/app/views/partials/snippet_form.blade.php:
--------------------------------------------------------------------------------
1 | @if(empty($snippet->title))
2 | {{ Form::model($snippet, ['route' => 'snippet.store']) }}
3 | @else
4 | {{ Form::model($snippet, ['route' => ['snippet.update', $snippet->id], 'method' => 'PUT']) }}
5 | @endif
6 |
7 | Snippet Title
8 | {{ Form::text('title', null, ['class' => 'form-control', 'id' => 'title', 'placeholder' => 'Enter a descriptive title', 'autofocus']) }}
9 |
10 |
11 | Description
12 | {{ Form::textarea('description', null, ['class' => 'form-control', 'id' => 'description', 'placeholder' => 'Describe exactly what your snippet achieves or which behaviour it adds.', 'rows' => '3']) }}
13 | @include('partials.markdown_help')
14 |
15 |
16 | Tags
17 | {{ Form::text('tags', implode(',', $snippet->tagnames()), ['class' => 'form-control', 'id' => 'tags', 'placeholder' => 'Choose tags', 'data-role' => 'tagsinput']) }}
18 |
19 |
20 | Snippet
21 | {{ Form::textarea('body', null, ['class' => 'form-control snippet', 'id' => 'body', 'placeholder' => 'Paste your snippet here.', 'rows' => '6']) }}
22 |
23 |
Submit
24 | {{ Form::close() }}
25 |
26 | @section('script')
27 | {{ HTML::script('js/vendor/bootstrap-tagsinput.min.js') }}
28 | {{ HTML::script('js/vendor/typeahead.bundle.min.js') }}
29 | {{ HTML::script('js/tagging.js') }}
30 | @stop
31 |
--------------------------------------------------------------------------------
/app/views/partials/navbar.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
19 | @if(Auth::guest())
20 |
23 | @else
24 |
28 | @endif
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/routes.php:
--------------------------------------------------------------------------------
1 | 'home', 'uses' => 'PagesController@home']);
3 | Route::get('faq', ['as' => 'faq', 'uses' => 'PagesController@faq']);
4 | Route::get('sitemap.xml', 'PagesController@sitemap');
5 |
6 | Route::get('feed', 'FeedController@index');
7 |
8 | Route::get('search', ['as' => 'search', 'uses' => 'SearchController@index']);
9 |
10 | Route::model('snippet', 'Vimrcfu\Snippets\Snippet');
11 | Route::get('snippet/hot', ['as' => 'snippet.hot', 'uses' => 'SnippetsController@hot']);
12 | Route::resource('snippet', 'SnippetsController', ['except' => 'destroy']);
13 | Route::get('snippet/{id}/up', ['as' => 'vote.up', 'uses' => 'VotesController@up']);
14 | Route::get('snippet/{id}/down', ['as' => 'vote.down', 'uses' => 'VotesController@down']);
15 |
16 | Route::model('user', 'Vimrcfu\Users\User');
17 | Route::get('login', ['as' => 'login', 'uses' => 'UsersController@login']);
18 | Route::get('logout', ['as' => 'logout', 'uses' => 'UsersController@logout']);
19 | Route::resource('user', 'UsersController', ['only' => 'show']);
20 | Route::get('user/{user}/upvotes', ['as' => 'user.votes', 'uses' => 'UsersController@upvotes']);
21 |
22 | Route::model('comment', 'Vimrcfu\Comments\Comment');
23 | Route::resource('comment', 'CommentsController', ['only' => ['store', 'edit', 'update']]);
24 |
25 | Route::get('tag/search/{name}', ['uses' => 'TagsController@search']);
26 | Route::get('tag/prefetch', ['uses' => 'TagsController@prefetch']);
27 | Route::get('tag/{slug}', ['as' => 'tag.show', 'uses' => 'TagsController@show']);
28 |
29 | Route::get('snake', function () {
30 | return Response::view('errors.503', ['title' => 'Snake'], 503);
31 | });
32 |
--------------------------------------------------------------------------------
/app/controllers/CommentsController.php:
--------------------------------------------------------------------------------
1 | beforeFilter('auth', ['only' => ['store', 'edit', 'update']]);
19 | $this->repository = $repository;
20 | }
21 |
22 | /**
23 | * Stores new Comment in storage.
24 | *
25 | * @return mixed
26 | */
27 | public function store()
28 | {
29 | $comment = $this->repository->create(Input::all());
30 |
31 | return Redirect::route('snippet.show', $comment->snippet->id);
32 | }
33 |
34 | /**
35 | * Shows the form for editing a Comment.
36 | *
37 | * @param Vimrcfu\Comments\Comment $comment
38 | * @return mixed
39 | */
40 | public function edit(Comment $comment)
41 | {
42 | if ( Auth::user()->id != $comment->user_id )
43 | {
44 | return Redirect::home();
45 | }
46 |
47 | return View::make('comments.edit', compact('comment'));
48 | }
49 |
50 | /**
51 | * Update a Comment in storage.
52 | *
53 | * @param Vimrcfu\Comments\Comment $comment
54 | * @return mixed
55 | */
56 | public function update(Comment $comment)
57 | {
58 | if ( Auth::user()->id != $comment->user_id )
59 | {
60 | return Redirect::home();
61 | }
62 |
63 | $comment = $this->repository->update($comment, Input::all());
64 |
65 | return Redirect::route('snippet.show', $comment->snippet->id);
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 |
9 | /*
10 | |--------------------------------------------------------------------------
11 | | Register The Auto Loader
12 | |--------------------------------------------------------------------------
13 | |
14 | | Composer provides a convenient, automatically generated class loader
15 | | for our application. We just need to utilize it! We'll require it
16 | | into the script here so that we do not have to worry about the
17 | | loading of any our classes "manually". Feels great to relax.
18 | |
19 | */
20 |
21 | require __DIR__.'/../bootstrap/autoload.php';
22 |
23 | /*
24 | |--------------------------------------------------------------------------
25 | | Turn On The Lights
26 | |--------------------------------------------------------------------------
27 | |
28 | | We need to illuminate PHP development, so let's turn on the lights.
29 | | This bootstraps the framework and gets it ready for use, then it
30 | | will load up this application so that we can run it and send
31 | | the responses back to the browser and delight these users.
32 | |
33 | */
34 |
35 | $app = require_once __DIR__.'/../bootstrap/start.php';
36 |
37 | /*
38 | |--------------------------------------------------------------------------
39 | | Run The Application
40 | |--------------------------------------------------------------------------
41 | |
42 | | Once we have the application, we can simply call the run method,
43 | | which will execute the request and send the response back to
44 | | the client's browser allowing them to enjoy the creative
45 | | and wonderful application we have whipped up for them.
46 | |
47 | */
48 |
49 | $app->run();
50 |
--------------------------------------------------------------------------------
/app/config/remote.php:
--------------------------------------------------------------------------------
1 | 'production',
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Remote Server Connections
21 | |--------------------------------------------------------------------------
22 | |
23 | | These are the servers that will be accessible via the SSH task runner
24 | | facilities of Laravel. This feature radically simplifies executing
25 | | tasks on your servers, such as deploying out these applications.
26 | |
27 | */
28 |
29 | 'connections' => array(
30 |
31 | 'production' => array(
32 | 'host' => '',
33 | 'username' => '',
34 | 'password' => '',
35 | 'key' => '',
36 | 'keyphrase' => '',
37 | 'root' => '/var/www',
38 | ),
39 |
40 | ),
41 |
42 | /*
43 | |--------------------------------------------------------------------------
44 | | Remote Server Groups
45 | |--------------------------------------------------------------------------
46 | |
47 | | Here you may list connections under a single group name, which allows
48 | | you to easily access all of the servers at once using a short name
49 | | that is extremely easy to remember, such as "web" or "database".
50 | |
51 | */
52 |
53 | 'groups' => array(
54 |
55 | 'web' => array('production')
56 |
57 | ),
58 |
59 | );
60 |
--------------------------------------------------------------------------------
/app/views/pages/feed.blade.php:
--------------------------------------------------------------------------------
1 |
3 |
11 | '; ?>
12 |
13 |
14 | vimrcfu - Share your best vimrc snippets.
15 |
16 | {{ Config::get('app.url') }}
17 | Gather your vimrc snippets on this site and let others learn from your fu.
18 | {{ \Carbon\Carbon::createFromTimeStamp(time())->toRssString() }}
19 | en-US
20 | hourly
21 | 1
22 | http://vimrcfu.com
23 | @foreach($snippets as $snippet)
24 | -
25 |
{{ Text::xmlentities($snippet->title) }}
26 | {{ Config::get('app.url') }}/snippet/{{ $snippet->id }}
27 | {{ $snippet->created_at->toRssString() }}
28 | user->name }}]]>
29 | http://vimrcfu.com/snippet/{{ $snippet->id }}
30 | description) }}]]>
31 | {{ Text::renderForRss($snippet->description) }}
{{ htmlentities($snippet->body) }} ]]>
32 |
33 | @endforeach
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/views/pages/home.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.main')
2 |
3 | @section('title', 'Share your best vimrc snippets')
4 |
5 | @section('content')
6 |
7 |
8 |
9 |
Share your knowledge
10 |
Gather your vimrc snippets on this site and let others learn from your fu .
11 |
Post a new snippet »
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
New Snippets
20 | @foreach($snippets as $snippet)
21 | @include('partials.snippet', ['img' => true])
22 | @endforeach
23 |
28 |
29 |
30 |
31 |
32 |
33 | @include('partials.search_form')
34 |
35 |
36 |
37 |
38 |
39 | @include('partials.statistics')
40 |
41 |
42 |
43 |
44 |
45 | @include('partials.tagcloud')
46 |
47 |
48 |
49 |
50 |
51 | {{ Text::renderInclude('news') }}
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | @stop
61 |
--------------------------------------------------------------------------------
/bootstrap/paths.php:
--------------------------------------------------------------------------------
1 | __DIR__.'/../app',
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Public Path
21 | |--------------------------------------------------------------------------
22 | |
23 | | The public path contains the assets for your web application, such as
24 | | your JavaScript and CSS files, and also contains the primary entry
25 | | point for web requests into these applications from the outside.
26 | |
27 | */
28 |
29 | 'public' => __DIR__.'/../public',
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Base Path
34 | |--------------------------------------------------------------------------
35 | |
36 | | The base path is the root of the Laravel installation. Most likely you
37 | | will not need to change this value. But, if for some wild reason it
38 | | is necessary you will do so here, just proceed with some caution.
39 | |
40 | */
41 |
42 | 'base' => __DIR__.'/..',
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Storage Path
47 | |--------------------------------------------------------------------------
48 | |
49 | | The storage path is used by Laravel to store cached Blade views, logs
50 | | and other pieces of information. You may modify the path here when
51 | | you want to change the location of this directory for your apps.
52 | |
53 | */
54 |
55 | 'storage' => __DIR__.'/../app/storage',
56 |
57 | );
58 |
--------------------------------------------------------------------------------
/app/views/users/show.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.main')
2 |
3 | @section('title', $user->name)
4 |
5 | @section('content')
6 |
7 |
8 |
9 |
10 |
11 |
{{ $user->name }}
12 |
13 |
14 |
15 |
16 |
37 |
38 |
39 |
40 |
41 | @include('partials.paginator')
42 |
43 |
44 | @foreach($snippets as $snippet)
45 | @if(Request::is('user/*/upvotes'))
46 | @include('partials.snippet', ['img' => true])
47 | @else
48 | @include('partials.snippet', ['img' => false])
49 | @endif
50 | @endforeach
51 |
52 |
53 | @include('partials.paginator')
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | @stop
62 |
--------------------------------------------------------------------------------
/public/js/vendor/bootstrap-tagsinput.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"dist/bootstrap-tagsinput-angular.min.js","sources":["src/bootstrap-tagsinput-angular.js"],"names":["angular","module","directive","getItemProperty","scope","property","isFunction","$parent","item","undefined","restrict","model","template","replace","link","element","attrs","$","isArray","select","typeaheadSourceArray","typeaheadSource","split","length","tagsinput","options","typeahead","source","itemValue","itemvalue","itemText","itemtext","confirmKeys","confirmkeys","JSON","parse","tagClass","tagclass","i","on","event","indexOf","push","idx","splice","prev","slice","$watch","added","filter","removed"],"mappings":";;;;;AAAAA,QAAQC,OAAO,0BACdC,UAAU,sBAAuB,WAEhC,QAASC,GAAgBC,EAAOC,GAC9B,MAAKA,GAGDL,QAAQM,WAAWF,EAAMG,QAAQF,IAC5BD,EAAMG,QAAQF,GAEhB,SAASG,GACd,MAAOA,GAAKH,IANLI,OAUX,OACEC,SAAU,KACVN,OACEO,MAAO,YAETC,SAAU,6BACVC,SAAS,EACTC,KAAM,SAASV,EAAOW,EAASC,GAC7BC,EAAE,WACKjB,QAAQkB,QAAQd,EAAMO,SACzBP,EAAMO,SAER,IAAIQ,GAASF,EAAE,SAAUF,GACrBK,EAAuBJ,EAAMK,gBAAkBL,EAAMK,gBAAgBC,MAAM,KAAO,KAClFD,EAAkBD,EACjBA,EAAqBG,OAAS,EAC3BnB,EAAMG,QAAQa,EAAqB,IAAIA,EAAqB,IAC1DhB,EAAMG,QAAQa,EAAqB,IACvC,IAEND,GAAOK,UAAUpB,EAAMG,QAAQS,EAAMS,SAAW,MAC9CC,WACEC,OAAW3B,QAAQM,WAAWe,GAAmBA,EAAkB,MAErEO,UAAWzB,EAAgBC,EAAOY,EAAMa,WACxCC,SAAW3B,EAAgBC,EAAOY,EAAMe,UACxCC,YAAc7B,EAAgBC,EAAOY,EAAMiB,aAAeC,KAAKC,MAAMnB,EAAMiB,cAAgB,IAC3FG,SAAWpC,QAAQM,WAAWF,EAAMG,QAAQS,EAAMqB,WAAajC,EAAMG,QAAQS,EAAMqB,UAAY,WAAiB,MAAOrB,GAAMqB,WAG/H,KAAK,GAAIC,GAAI,EAAGA,EAAIlC,EAAMO,MAAMY,OAAQe,IACtCnB,EAAOK,UAAU,MAAOpB,EAAMO,MAAM2B,GAGtCnB,GAAOoB,GAAG,YAAa,SAASC,GACU,KAApCpC,EAAMO,MAAM8B,QAAQD,EAAMhC,OAC5BJ,EAAMO,MAAM+B,KAAKF,EAAMhC,QAG3BW,EAAOoB,GAAG,cAAe,SAASC,GAChC,GAAIG,GAAMvC,EAAMO,MAAM8B,QAAQD,EAAMhC,KACxB,MAARmC,GACFvC,EAAMO,MAAMiC,OAAOD,EAAK,IAK5B,IAAIE,GAAOzC,EAAMO,MAAMmC,OACvB1C,GAAM2C,OAAO,QAAS,WACpB,GAEIT,GAFAU,EAAQ5C,EAAMO,MAAMsC,OAAO,SAASX,GAAI,MAA2B,KAApBO,EAAKJ,QAAQH,KAC5DY,EAAUL,EAAKI,OAAO,SAASX,GAAI,MAAkC,KAA3BlC,EAAMO,MAAM8B,QAAQH,IAMlE,KAHAO,EAAOzC,EAAMO,MAAMmC,QAGdR,EAAI,EAAGA,EAAIY,EAAQ3B,OAAQe,IAC9BnB,EAAOK,UAAU,SAAU0B,EAAQZ,GAOrC,KAHAnB,EAAOK,UAAU,WAGZc,EAAI,EAAGA,EAAIU,EAAMzB,OAAQe,IAC5BnB,EAAOK,UAAU,MAAOwB,EAAMV,MAE/B"}
--------------------------------------------------------------------------------
/public/js/vendor/html5shiv.js:
--------------------------------------------------------------------------------
1 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
2 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x";
3 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="
";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
4 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
5 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d
repository = $repository;
29 | $this->tagsRepository = $tagsRepository;
30 | }
31 |
32 | /**
33 | * Displays the home page.
34 | *
35 | * @return Response
36 | */
37 | public function home()
38 | {
39 | $newSnippets = $this->repository->newSnippets();
40 | $topSnippet = $this->repository->topSnippet();
41 | $topCommented = $this->repository->topCommented();
42 | $topTags = $this->tagsRepository->topTags();
43 | $title = 'Popular Tags';
44 |
45 | return View::make('pages.home')
46 | ->withSnippets($newSnippets)
47 | ->withSnippetsCount(Snippet::remember(5)->get()->count())
48 | ->withCommentsCount(Comment::remember(5)->get()->count())
49 | ->withUsersCount(User::remember(5)->get()->count())
50 | ->withTopSnippet($topSnippet)
51 | ->withTopComments($topCommented)
52 | ->withTags($topTags)
53 | ->withTitle($title);
54 |
55 | }
56 |
57 | /**
58 | * Displays Frequently Asked Questions.
59 | *
60 | * @return void
61 | */
62 | public function faq()
63 | {
64 | return View::make('pages.markdown')
65 | ->withTitle('Frequently Asked Questions')
66 | ->withFile('faq');
67 | }
68 |
69 | /**
70 | * Displays the XML sitemap.
71 | *
72 | * @return void
73 | */
74 | public function sitemap()
75 | {
76 | $static = [
77 | 'faq',
78 | 'search',
79 | 'snippet'
80 | ];
81 |
82 | return View::make('pages.sitemap')
83 | ->with('static', $static)
84 | ->with('snippets', Snippet::all())
85 | ->with('tags', Tag::all())
86 | ->with('users', User::all());
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/app/config/auth.php:
--------------------------------------------------------------------------------
1 | 'eloquent',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Authentication Model
23 | |--------------------------------------------------------------------------
24 | |
25 | | When using the "Eloquent" authentication driver, we need to know which
26 | | Eloquent model should be used to retrieve your users. Of course, it
27 | | is often just the "User" model but you may use whatever you like.
28 | |
29 | */
30 |
31 | 'model' => 'Vimrcfu\Users\User',
32 |
33 | /*
34 | |--------------------------------------------------------------------------
35 | | Authentication Table
36 | |--------------------------------------------------------------------------
37 | |
38 | | When using the "Database" authentication driver, we need to know which
39 | | table should be used to retrieve your users. We have chosen a basic
40 | | default value but you may easily change it to any table you like.
41 | |
42 | */
43 |
44 | 'table' => 'users',
45 |
46 | /*
47 | |--------------------------------------------------------------------------
48 | | Password Reminder Settings
49 | |--------------------------------------------------------------------------
50 | |
51 | | Here you may set the settings for password reminders, including a view
52 | | that should be used as your password reminder e-mail. You will also
53 | | be able to set the name of the table that holds the reset tokens.
54 | |
55 | | The "expire" time is the number of minutes that the reminder should be
56 | | considered valid. This security feature keeps tokens short-lived so
57 | | they have less time to be guessed. You may change this as needed.
58 | |
59 | */
60 |
61 | 'reminder' => array(
62 |
63 | 'email' => 'emails.auth.reminder',
64 |
65 | 'table' => 'password_reminders',
66 |
67 | 'expire' => 60,
68 |
69 | ),
70 |
71 | );
72 |
--------------------------------------------------------------------------------
/app/Vimrcfu/Tags/EloquentTagsRepository.php:
--------------------------------------------------------------------------------
1 | get();
16 | }
17 |
18 | public function getByName($name)
19 | {
20 | return Tag::whereName($name)->first();
21 | }
22 |
23 | /**
24 | * @var Vimrcfu\Snippets\Snippet $snippet
25 | * @var Vimrcfu\Tags\Tag $tags
26 | */
27 | public function updateTags($snippet, $tagNamesString)
28 | {
29 | $tagNamesArray = explode(',', $tagNamesString);
30 | $snippetTagNamesArray = $snippet->tagnames();
31 |
32 | $tagNamesToRemove = array_diff($snippetTagNamesArray, $tagNamesArray);
33 | $tagNamesToAdd = array_diff($tagNamesArray, $snippetTagNamesArray);
34 |
35 | foreach($tagNamesToRemove as $tagname)
36 | {
37 | $tag = $this->getByName($tagname);
38 | $snippet->tags()->detach($tag);
39 | }
40 |
41 | foreach($tagNamesToAdd as $tagname)
42 | {
43 | $tagname = trim($tagname);
44 | if ($tagname) {
45 | $tag = Tag::firstOrCreate(['name' => $tagname, 'slug' => Str::slug($tagname)]);
46 | $snippet->tags()->attach($tag->id);
47 | }
48 | }
49 | }
50 |
51 | /**
52 | * @return array
53 | */
54 | public static function topTags()
55 | {
56 | $topTags = Cache::remember('topTags', 5, function ()
57 | {
58 | $topTagsResult = DB::select(DB::raw('
59 | SELECT tags.name, tag_id, count(tag_id) count, tags.slug FROM taggables
60 | JOIN tags ON taggables.tag_id = tags.id
61 | GROUP BY tag_id ORDER BY count DESC LIMIT 14'
62 | ));
63 |
64 | return (isset($topTagsResult)) ? $topTagsResult : [];
65 | });
66 |
67 | $topTags = array_map(function ($tags) {
68 | return (object) [
69 | 'id' => $tags->tag_id,
70 | 'name' => $tags->name,
71 | 'slug' => $tags->slug
72 | ];
73 | }, $topTags);
74 |
75 | return $topTags;
76 | }
77 |
78 | /**
79 | * @param string search
80 | * @param int $count
81 | * @return mixed
82 | */
83 | public function relatedTags($search, $count = 20)
84 | {
85 | return Tag::where('name', 'LIKE', '%' . $search . '%')->take($count)->get();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/config/queue.php:
--------------------------------------------------------------------------------
1 | 'sync',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | Queue Connections
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may configure the connection information for each server that
26 | | is used by your application. A default configuration has been added
27 | | for each back-end shipped with Laravel. You are free to add more.
28 | |
29 | */
30 |
31 | 'connections' => array(
32 |
33 | 'sync' => array(
34 | 'driver' => 'sync',
35 | ),
36 |
37 | 'beanstalkd' => array(
38 | 'driver' => 'beanstalkd',
39 | 'host' => 'localhost',
40 | 'queue' => 'default',
41 | 'ttr' => 60,
42 | ),
43 |
44 | 'sqs' => array(
45 | 'driver' => 'sqs',
46 | 'key' => 'your-public-key',
47 | 'secret' => 'your-secret-key',
48 | 'queue' => 'your-queue-url',
49 | 'region' => 'us-east-1',
50 | ),
51 |
52 | 'iron' => array(
53 | 'driver' => 'iron',
54 | 'host' => 'mq-aws-us-east-1.iron.io',
55 | 'token' => 'your-token',
56 | 'project' => 'your-project-id',
57 | 'queue' => 'your-queue-name',
58 | 'encrypt' => true,
59 | ),
60 |
61 | 'redis' => array(
62 | 'driver' => 'redis',
63 | 'queue' => 'default',
64 | ),
65 |
66 | ),
67 |
68 | /*
69 | |--------------------------------------------------------------------------
70 | | Failed Queue Jobs
71 | |--------------------------------------------------------------------------
72 | |
73 | | These options configure the behavior of failed queue job logging so you
74 | | can control which database and table are used to store the jobs that
75 | | have failed. You may change them to any database / table you wish.
76 | |
77 | */
78 |
79 | 'failed' => array(
80 |
81 | 'database' => 'mysql', 'table' => 'failed_jobs',
82 |
83 | ),
84 |
85 | );
86 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guide
2 |
3 | This page contains guidelines for contributing to **vimrcfu**. Please review these guidelines before submitting any pull requests to the project.
4 |
5 | This contributing guide is based on the original [Laravel Contribution Guide](https://github.com/laravel/framework/blob/4.1/CONTRIBUTING.md).
6 |
7 | ## Which Branch?
8 |
9 | All changes targeting the current version should be sent to the `dev` branch.
10 |
11 | ## Pull Requests
12 |
13 | Before sending a pull request for a new feature, you should first create an issue with `[Proposal]` in the title. The proposal should describe the new feature, as well as implementation ideas. The proposal will then be reviewed and either approved or denied. Once a proposal is approved, a pull request may be created implementing the new feature.
14 |
15 | Pull requests for bugs may be sent without creating any proposal issue. If you believe that you know of a solution for a bug that has been filed on GitHub, please leave a comment detailing your proposed fix.
16 |
17 | ### Feature Requests
18 |
19 | If you have an idea for a new feature you would like to see added to **vimrcfu**, you may create an issue on GitHub with `[Request]` in the title. The feature request will then be reviewed.
20 |
21 | ## Coding Standards
22 |
23 | Adherence to coding standard can be enforced with [PHP Coding Standards Fixer](http://cs.sensiolabs.org).
24 |
25 | Install with `composer global require fabpot/php-cs-fixer @stable` and then in the direcotry where you checked out the repository execute: `php-cs-fixer fix --config-file="config.php_cs"`
26 |
27 | The following should be adhered to throughout the code base ([Laravel 4.2 Coding Style](http://laravel.com/docs/4.2/contributions#coding-style)):
28 | * Namespace declarations should be on the same line as `title)
4 |
5 | @section('content')
6 |
7 |
8 |
9 |
10 |
11 |
{{{ $snippet->title }}}
12 |
13 |
14 |
15 |
16 | score; ?>
17 |
{{ $score }} {{ Str::plural('Point', $score) }}
18 | @if(Auth::check())
19 | hasUserVoted(Auth::user()->id); ?>
20 |
21 |
22 | @endif
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | {{ HTML::linkRoute('user.show', $snippet->user->name, $snippet->user->id) }}
33 |
{{ $snippet->created_at->diffForHumans() }}
34 | @if(Auth::check() && Auth::user()->id == $snippet->user_id)
35 |
Edit »
36 | @endif
37 |
38 |
39 |
40 | {{ Text::render($snippet->description) }}
41 |
{{{ $snippet->body }}}
42 |
43 |
44 | tags; ?>
45 | @include("partials.tagcloud", ['title' => ''])
46 |
47 |
48 |
49 | @if($snippet->comments->count() || Auth::check())
50 |
51 | @endif
52 |
53 |
54 |
55 | @if(Auth::check())
56 | @include('partials.comment_form')
57 | @endif
58 |
59 |
60 | @foreach($snippet->comments as $comment)
61 | @include('partials.comment')
62 | @endforeach
63 |
64 |
65 |
66 |
67 |
68 | @stop
69 |
--------------------------------------------------------------------------------
/app/views/layouts/main.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | @yield('title') | vimrcfu
6 |
7 |
8 |
9 | {{ HTML::style('css/font-awesome.css') }}
10 | {{ HTML::style('css/bootstrap.min.css') }}
11 | {{ HTML::style('css/bootstrap-social.css') }}
12 | {{ HTML::style('css/animate.min.css') }}
13 | {{ HTML::style('css/main.css?v=1.2') }}
14 |
18 |
19 |
20 |
21 | @include('partials.navbar')
22 |
23 | @yield('content')
24 |
25 |
26 |
27 |
28 |
29 |
30 | © {{ date('Y') }} Florian Beer - made with Vim
31 | Source code on GitHub
32 | Hosted by 42dev
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | {{ HTML::script('js/vendor/bootstrap.min.js') }}
43 | {{ HTML::script('js/vendor/wow.min.js') }}
44 |
47 | {{ HTML::script('js/main.js') }}
48 | @yield('script')
49 | @if(getenv('PIWIK_URL'))
50 | @include('partials.tracking')
51 | @endif
52 |
53 |
54 |
--------------------------------------------------------------------------------
/bootstrap/start.php:
--------------------------------------------------------------------------------
1 | detectEnvironment(function(){
28 |
29 | return getenv('APP_ENV') ?: 'local';
30 |
31 | });
32 |
33 | /*
34 | |--------------------------------------------------------------------------
35 | | Bind Paths
36 | |--------------------------------------------------------------------------
37 | |
38 | | Here we are binding the paths configured in paths.php to the app. You
39 | | should not be changing these here. If you need to change these you
40 | | may do so within the paths.php file and they will be bound here.
41 | |
42 | */
43 |
44 | $app->bindInstallPaths(require __DIR__.'/paths.php');
45 |
46 | /*
47 | |--------------------------------------------------------------------------
48 | | Load The Application
49 | |--------------------------------------------------------------------------
50 | |
51 | | Here we will load this Illuminate application. We will keep this in a
52 | | separate location so we can isolate the creation of an application
53 | | from the actual running of the application with a given request.
54 | |
55 | */
56 |
57 | $framework = $app['path.base'].
58 | '/vendor/laravel/framework/src';
59 |
60 | require $framework.'/Illuminate/Foundation/start.php';
61 |
62 | /*
63 | |--------------------------------------------------------------------------
64 | | Return The Application
65 | |--------------------------------------------------------------------------
66 | |
67 | | This script returns the application instance. The instance is given to
68 | | the calling script so we can separate the building of the instances
69 | | from the actual running of the application and sending responses.
70 | |
71 | */
72 |
73 | return $app;
74 |
--------------------------------------------------------------------------------
/app/filters.php:
--------------------------------------------------------------------------------
1 | setRequestForConsoleEnvironment();
45 |
46 | $artisan = Illuminate\Console\Application::start($app);
47 |
48 | /*
49 | |--------------------------------------------------------------------------
50 | | Run The Artisan Application
51 | |--------------------------------------------------------------------------
52 | |
53 | | When we run the console application, the current CLI command will be
54 | | executed in this console and the response sent back to a terminal
55 | | or another output device for the developers. Here goes nothing!
56 | |
57 | */
58 |
59 | $status = $artisan->run();
60 |
61 | /*
62 | |--------------------------------------------------------------------------
63 | | Shutdown The Application
64 | |--------------------------------------------------------------------------
65 | |
66 | | Once Artisan has finished running. We will fire off the shutdown events
67 | | so that any final work may be done by the application before we shut
68 | | down the process. This is the last thing to happen to the request.
69 | |
70 | */
71 |
72 | $app->shutdown();
73 |
74 | exit($status);
75 |
--------------------------------------------------------------------------------
/bootstrap/autoload.php:
--------------------------------------------------------------------------------
1 | beforeFilter('auth', ['only' => ['create', 'store', 'edit', 'update']]);
19 | $this->repository = $repository;
20 | }
21 |
22 | /**
23 | * Displays all Snippets paginated.
24 | *
25 | * @return mixed
26 | */
27 | public function index()
28 | {
29 | $snippets = $this->repository->snippetsWithCommentsAndUsersPaginated();
30 |
31 | return View::make('snippets.index', compact('snippets'));
32 | }
33 |
34 | public function hot()
35 | {
36 | $snippets = $this->repository->snippetsWithCommentsAndUsersPaginated('hot');
37 |
38 | return View::make('snippets.index', compact('snippets'))
39 | ->with('title', 'Hot Snippets');
40 | }
41 |
42 | /**
43 | * Shows the form for creating a new Snippet.
44 | *
45 | * @return mixed
46 | */
47 | public function create()
48 | {
49 | return View::make('snippets.create')->withSnippet(new Snippet());
50 | }
51 |
52 | /**
53 | * Stores a new Snippet.
54 | *
55 | * @return mixed
56 | */
57 | public function store()
58 | {
59 | $snippet = $this->repository->create(Input::all());
60 |
61 | return Redirect::route('snippet.show', $snippet->id);
62 | }
63 |
64 | /**
65 | * Displays a Snippet.
66 | *
67 | * @param Vimrcfu\Snippets\Snippet $snippet
68 | * @return mixed
69 | */
70 | public function show(Snippet $snippet)
71 | {
72 | return View::make('snippets.show', compact('snippet'));
73 | }
74 |
75 | /**
76 | * Shows the form for editing a Snippet.
77 | *
78 | * @param Vimrcfu\Snippets\Snippet $snippet
79 | * @return mixed
80 | */
81 | public function edit(Snippet $snippet)
82 | {
83 | if ( Auth::user()->id != $snippet->user_id )
84 | {
85 | return Redirect::home();
86 | }
87 |
88 | return View::make('snippets.edit', compact('snippet'));
89 | }
90 |
91 | /**
92 | * Updates a Snippet in storage.
93 | *
94 | * @param Vimrcfu\Snippets\Snippet $snippet
95 | * @return mixed
96 | */
97 | public function update(Snippet $snippet)
98 | {
99 | if ( Auth::user()->id != $snippet->user_id )
100 | {
101 | return Redirect::home();
102 | }
103 |
104 | $this->repository->update($snippet, Input::all());
105 |
106 | return Redirect::route('snippet.show', $snippet->id);
107 |
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/app/views/errors/503.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ $title }} | vimrcfu
6 |
7 |
8 |
9 | {{ HTML::style('css/font-awesome.css') }}
10 | {{ HTML::style('css/bootstrap.min.css') }}
11 | {{ HTML::style('css/bootstrap-social.css') }}
12 | {{ HTML::style('css/animate.min.css') }}
13 | {{ HTML::style('css/main.css?v=1.2') }}
14 |
18 |
19 |
20 |
36 |
37 |
38 |
39 |
40 |
41 | {{ $title }}
42 |
43 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | {{ HTML::script('js/vendor/bootstrap.min.js') }}
55 | {{ HTML::script('js/vendor/wow.min.js') }}
56 | {{ HTML::script('js/snake.js') }}
57 |
60 | {{ HTML::script('js/main.js') }}
61 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/app/config/cache.php:
--------------------------------------------------------------------------------
1 | 'memcached',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | File Cache Location
23 | |--------------------------------------------------------------------------
24 | |
25 | | When using the "file" cache driver, we need a location where the cache
26 | | files may be stored. A sensible default has been specified, but you
27 | | are free to change it to any other place on disk that you desire.
28 | |
29 | */
30 |
31 | 'path' => storage_path().'/cache',
32 |
33 | /*
34 | |--------------------------------------------------------------------------
35 | | Database Cache Connection
36 | |--------------------------------------------------------------------------
37 | |
38 | | When using the "database" cache driver you may specify the connection
39 | | that should be used to store the cached items. When this option is
40 | | null the default database connection will be utilized for cache.
41 | |
42 | */
43 |
44 | 'connection' => null,
45 |
46 | /*
47 | |--------------------------------------------------------------------------
48 | | Database Cache Table
49 | |--------------------------------------------------------------------------
50 | |
51 | | When using the "database" cache driver we need to know the table that
52 | | should be used to store the cached items. A default table name has
53 | | been provided but you're free to change it however you deem fit.
54 | |
55 | */
56 |
57 | 'table' => 'cache',
58 |
59 | /*
60 | |--------------------------------------------------------------------------
61 | | Memcached Servers
62 | |--------------------------------------------------------------------------
63 | |
64 | | Now you may specify an array of your Memcached servers that should be
65 | | used when utilizing the Memcached cache driver. All of the servers
66 | | should contain a value for "host", "port", and "weight" options.
67 | |
68 | */
69 |
70 | 'memcached' => array(
71 |
72 | array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),
73 |
74 | ),
75 |
76 | /*
77 | |--------------------------------------------------------------------------
78 | | Cache Key Prefix
79 | |--------------------------------------------------------------------------
80 | |
81 | | When utilizing a RAM based store such as APC or Memcached, there might
82 | | be other applications utilizing the same cache. So, we'll specify a
83 | | value to get prefixed to all our keys so we can avoid collisions.
84 | |
85 | */
86 |
87 | 'prefix' => 'vimrcfu',
88 |
89 | );
90 |
--------------------------------------------------------------------------------
/app/controllers/UsersController.php:
--------------------------------------------------------------------------------
1 | repository = $repository;
18 | }
19 |
20 | /**
21 | * Persist new User with GitHub data then log in.
22 | *
23 | * @return mixed
24 | */
25 | public function login()
26 | {
27 | $code = Request::get('code');
28 | $github = OAuth::consumer('GitHub');
29 |
30 | if ( ! empty($code))
31 | {
32 | $token = $github->requestAccessToken($code);
33 | $result = json_decode($github->request('user'), true);
34 |
35 | if ( empty($result['name']) )
36 | {
37 | $result['name'] = $result['login'];
38 | }
39 |
40 | $result['email'] = last(json_decode($github->request('user/emails'), true));
41 |
42 | $githubData = [
43 | 'github_id' => $result['id'],
44 | 'github_url' => $result['html_url'],
45 | 'avatar_url' => $result['avatar_url'],
46 | 'email' => $result['email'],
47 | 'name' => $result['name']
48 | ];
49 |
50 | Auth::login($this->repository->findOrCreate($githubData));
51 |
52 | return Redirect::intended();
53 | }
54 |
55 | return Redirect::to((string) OAuth::consumer('GitHub')->getAuthorizationUri());
56 | }
57 |
58 | /**
59 | * Log out User.
60 | *
61 | * @return mixed
62 | */
63 | public function logout()
64 | {
65 | Auth::logout();
66 |
67 | return Redirect::home();
68 | }
69 |
70 | /**
71 | * Shows a User with all Tags and paginated Snippets.
72 | *
73 | * @param Vimrcfu\Users\User $user
74 | * @return mixed
75 | */
76 | public function show($user)
77 | {
78 | $snippetsResult = $user->snippets();
79 | $total = $snippetsResult->count();
80 | $snippets = $snippetsResult->with('comments')->simplePaginate(10);
81 | $tags = $user->tags();
82 |
83 | return View::make('users.show', compact('user', 'snippets', 'total', 'tags'));
84 | }
85 |
86 | /**
87 | * Shows a User's upvoted Snippets
88 | *
89 | * @param Vimrcfu\Users\User $user
90 | * @return mixed
91 | */
92 | public function upvotes($user)
93 | {
94 | $snippetsResult = Vimrcfu\Snippets\Snippet::select('snippets.*')
95 | ->where('user_id', '!=', $user->id)
96 | ->whereHas('votes', function ($q) use ($user) {
97 | $q->where('user_id', $user->id)
98 | ->where('score', '=', '1');
99 | })->orderBy('created_at', 'DESC');
100 | $total = $user->snippets()->count();
101 | $snippets = $snippetsResult->simplePaginate(10);
102 | $tags = $user->tags();
103 |
104 | return View::make('users.show', compact('user', 'snippets', 'total', 'tags'));
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/app/start/global.php:
--------------------------------------------------------------------------------
1 | withErrors($exception->getErrors())
58 | ->withInput();
59 | });
60 |
61 | App::missing(function($exception)
62 | {
63 | return Response::view('errors.404', array(), 404);
64 | });
65 |
66 | /*
67 | |--------------------------------------------------------------------------
68 | | Maintenance Mode Handler
69 | |--------------------------------------------------------------------------
70 | |
71 | | The "down" Artisan command gives you the ability to put an application
72 | | into maintenance mode. Here, you will define what is displayed back
73 | | to the user if maintenance mode is in effect for the application.
74 | |
75 | */
76 |
77 | App::down(function()
78 | {
79 | return Response::view('errors.503', ['title' => 'Down for maintenance'], 503);
80 | });
81 |
82 | /*
83 | |--------------------------------------------------------------------------
84 | | Require The Filters File
85 | |--------------------------------------------------------------------------
86 | |
87 | | Next we will load the filters file for the application. This gives us
88 | | a nice separate location to store our route and application filter
89 | | definitions instead of putting them all in the main routes file.
90 | |
91 | */
92 |
93 | require app_path().'/filters.php';
94 |
--------------------------------------------------------------------------------
/app/Vimrcfu/Core/Text.php:
--------------------------------------------------------------------------------
1 | ))\/?.*?>/";
16 |
17 | return preg_replace($regex, '', $text);
18 | }
19 |
20 | /**
21 | * Creates clickable links from URLs.
22 | *
23 | * @param string $text
24 | * @return string
25 | */
26 | private function createExternalLinks($text)
27 | {
28 | $regex = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,63}([\w\.\/:\=\?\#\!-]*)/";
29 |
30 | return preg_replace($regex, '$0 ', $text);
31 | }
32 |
33 | /**
34 | * Constructs clickable internal links to Snippets.
35 | *
36 | * @param string $text
37 | * @param bool $absolute
38 | * @return string
39 | */
40 | private function createSnippetLinks($text, $absolute = false)
41 | {
42 | $regex = "/snippet#([0-9]*)(\/\S*)?/";
43 | if ( $absolute )
44 | {
45 | return preg_replace($regex, 'Snippet #$1 ', $text);
46 | }
47 |
48 | return preg_replace($regex, 'Snippet #$1 ', $text);
49 | }
50 |
51 | /**
52 | * Returns HTML from Markdown
53 | *
54 | * @param string $text
55 | * @return string
56 | */
57 | private function renderMarkdown($text)
58 | {
59 | return MarkdownExtra::defaultTransform($text);
60 | }
61 |
62 | /**
63 | * Returns HTML without unwanted tags
64 | * with external and internal links.
65 | *
66 | * @param string $text
67 | * @return string
68 | */
69 | public function render($text)
70 | {
71 | $text = $this->renderMarkdown($text);
72 | $text = $this->stripTags($text);
73 | $text = $this->createExternalLinks($text);
74 | $text = $this->createSnippetLinks($text);
75 |
76 | return $text;
77 | }
78 |
79 | /**
80 | * Returns HTML from Markdown file with all tags intact.
81 | *
82 | * @param string $filename
83 | * @return string
84 | */
85 | public function renderInclude($filename)
86 | {
87 | $text = \File::get(app_path().'/markdown/'.$filename.'.md');
88 | $text = $this->renderMarkdown($text);
89 | $text = $this->createSnippetLinks($text);
90 |
91 | return $text;
92 | }
93 |
94 | /**
95 | * Returns rendered HTML with absolute links for RSS.
96 | *
97 | * @param string $text
98 | * @return string
99 | */
100 | public function renderForRss($text)
101 | {
102 | $text = $this->renderMarkdown($text);
103 | $text = $this->stripTags($text);
104 | $text = $this->createExternalLinks($text);
105 | $text = $this->createSnippetLinks($text, true);
106 |
107 | return $text;
108 | }
109 |
110 | /**
111 | * Escape special characters for XML output.
112 | *
113 | * @param string $text
114 | * @return string
115 | */
116 | public function xmlentities($text)
117 | {
118 | $text = str_replace('&', '&', $text);
119 | $text = str_replace('<', '<', $text);
120 | $text = str_replace('>', '>', $text);
121 |
122 | return $text;
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/public/js/snake.js:
--------------------------------------------------------------------------------
1 | // Snake game from: http://thecodeplayer.com/walkthrough/html5-game-tutorial-make-a-snake-game-using-html5-canvas-jquery
2 |
3 | $(document).ready(function(){
4 | var canvas = $("#canvas")[0];
5 | var ctx = canvas.getContext("2d");
6 | var w = $("#canvas").width();
7 | var h = $("#canvas").height();
8 | var cw = 10;
9 | var d;
10 | var food;
11 | var score;
12 | var snake_array;
13 |
14 | function init()
15 | {
16 | d = "right";
17 | create_snake();
18 | create_food();
19 | score = 0;
20 | if(typeof game_loop != "undefined") clearInterval(game_loop);
21 | game_loop = setInterval(paint, 60);
22 | }
23 | init();
24 |
25 | function create_snake()
26 | {
27 | var length = 5;
28 | snake_array = [];
29 | for(var i = length-1; i>=0; i--)
30 | {
31 | snake_array.push({x: i, y:0});
32 | }
33 | }
34 |
35 | function create_food()
36 | {
37 | food = {
38 | x: Math.round(Math.random()*(w-cw)/cw),
39 | y: Math.round(Math.random()*(h-cw)/cw),
40 | };
41 | }
42 |
43 | function paint()
44 | {
45 | ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
46 | ctx.fillRect(0, 0, w, h);
47 | ctx.strokeStyle = "rgb(97, 95, 56)";
48 | ctx.strokeRect(0, 0, w, h);
49 |
50 | var nx = snake_array[0].x;
51 | var ny = snake_array[0].y;
52 | if(d == "right") nx++;
53 | else if(d == "left") nx--;
54 | else if(d == "up") ny--;
55 | else if(d == "down") ny++;
56 |
57 | if(nx == -1 || nx == w/cw || ny == -1 || ny == h/cw || check_collision(nx, ny, snake_array))
58 | {
59 | init();
60 | return;
61 | }
62 |
63 | if(nx == food.x && ny == food.y)
64 | {
65 | var tail = {x: nx, y: ny};
66 | score++;
67 | create_food();
68 | }
69 | else
70 | {
71 | var tail = snake_array.pop();
72 | tail.x = nx; tail.y = ny;
73 | }
74 |
75 | snake_array.unshift(tail);
76 |
77 | for(var i = 0; i < snake_array.length; i++)
78 | {
79 | var c = snake_array[i];
80 | paint_cell(c.x, c.y);
81 | }
82 |
83 | paint_cell(food.x, food.y);
84 | var score_text = "Score: " + score;
85 | ctx.fillText(score_text, 5, h-5);
86 | }
87 |
88 | function paint_cell(x, y)
89 | {
90 | ctx.fillStyle = "rgb(97, 95, 56)";
91 | ctx.fillRect(x*cw, y*cw, cw, cw);
92 | ctx.strokeStyle = "black";
93 | ctx.strokeRect(x*cw, y*cw, cw, cw);
94 | }
95 |
96 | function check_collision(x, y, array)
97 | {
98 | for(var i = 0; i < array.length; i++)
99 | {
100 | if(array[i].x == x && array[i].y == y)
101 | return true;
102 | }
103 | return false;
104 | }
105 |
106 | $(document).keydown(function(e){
107 | var key = e.which;
108 | if(key == "37" && d != "right") d = "left";
109 | else if(key == "38" && d != "down") d = "up";
110 | else if(key == "39" && d != "left") d = "right";
111 | else if(key == "40" && d != "up") d = "down";
112 | });
113 | });
114 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vimrcfu
2 |
3 | http://vimrcfu.com
4 |
5 | Made with [Laravel 4.2](http://laravel.com/docs/4.2)
6 |
7 | ---
8 |
9 | ## Set up
10 |
11 | * Clone the repository into a directory on your local machine (development) or server (production)
12 | * Follow the [configuration](#Configuration) steps below
13 | * **vimrcfu** uses Memcache for caching. If you don't want to install Memcache, set driver to `file` in `app/config/cache.php`.
14 | * Run `composer install`
15 | * Run `php artisan migrate`
16 | * Don't forget to smile once in a while!
17 |
18 |
19 | ## Configuration
20 |
21 | ### For development
22 |
23 | * Create a [GitHub application](https://github.com/settings/applications), for example "vimrcfu dev", with your local Homepage URL and Authorization callback URL (e.g. `http://vimrcfu.loc` and `http://vimrcfu.loc/login`) and note the Client ID and Client Secret GitHub generates for your.
24 | * Create the file `.env.local.php` in the directory where you cloned the repository with the following content:
25 |
26 | ``` php
27 | return [
28 | 'DB_HOST' => 'localhost', # Fill in your database host
29 | 'DB_NAME' => 'vimrcfu', # Fill in your database name
30 | 'DB_USER' => 'root', # Fill in your database username
31 | 'DB_PASSWORD' => '', # Fill in your database password
32 | 'APP_KEY' => '', # Choose a very random string with at least 32 characters
33 | 'GITHUB_CLIENT' => '', # Fill in your GitHub Client ID
34 | 'GITHUB_SECRET' => '', # Fill in your GitHub Client Secret
35 | 'PIWIK_URL' => '', # Fill in URL if you want Piwik tracking
36 | 'PIWIK_ID' => '', # Piwik site id
37 | ];
38 | ```
39 |
40 | ### For production
41 |
42 | * In your webserver set an environment variable called `APP_ENV` and give it a value of `production`.
43 |
44 | * For Apache put the following in your vhost configuration: `SetEnv APP_ENV production`
45 | * For nginx if you use php-fpm put the following in your location block: `fastcgi_param APP_ENV production;`
46 |
47 |
48 | * Create the file `.env.php` in the directory where you cloned the repository with the same contents as above, but fill in your production database settings, Client ID and Client Secret (create a new application on GitHub with the actual Homepage URL and Authorization callback URL for your production domain).
49 |
50 | ## Maintainer
51 |
52 | **vimrcfu** is currently maintained by [Florian Beer](http://github.com/florianbeer). If you have any questions please don't hesitate to get in touch.
53 |
54 | The best way to ask questions is via GitHub [issues](https://github.com/florianbeer/vimrcfu/issues) or via Twitter [@azath0th](https://twitter.com/azath0th).
55 |
56 | ## Contributing
57 |
58 | Please see [CONTRIBUTING](https://github.com/florianbeer/vimrcfu/blob/master/CONTRIBUTING.md) for details.
59 |
60 | ## License
61 |
62 | vimrcfu by Florian Beer | 42dev is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License .
63 |
64 | Please see [LICENSE](https://github.com/florianbeer/vimrcfu/blob/master/LICENSE.md) for more details.
65 |
66 |
--------------------------------------------------------------------------------
/app/config/database.php:
--------------------------------------------------------------------------------
1 | PDO::FETCH_CLASS,
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Default Database Connection Name
21 | |--------------------------------------------------------------------------
22 | |
23 | | Here you may specify which of the database connections below you wish
24 | | to use as your default connection for all database work. Of course
25 | | you may use many connections at once using the Database library.
26 | |
27 | */
28 |
29 | 'default' => 'mysql',
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Database Connections
34 | |--------------------------------------------------------------------------
35 | |
36 | | Here are each of the database connections setup for your application.
37 | | Of course, examples of configuring each database platform that is
38 | | supported by Laravel is shown below to make development simple.
39 | |
40 | |
41 | | All database work in Laravel is done through the PHP PDO facilities
42 | | so make sure you have the driver for your particular database of
43 | | choice installed on your machine before you begin development.
44 | |
45 | */
46 |
47 | 'connections' => array(
48 |
49 | 'sqlite' => array(
50 | 'driver' => 'sqlite',
51 | 'database' => __DIR__.'/../database/production.sqlite',
52 | 'prefix' => '',
53 | ),
54 |
55 | 'mysql' => array(
56 | 'driver' => 'mysql',
57 | 'host' => getenv('DB_HOST'),
58 | 'database' => getenv('DB_NAME'),
59 | 'username' => getenv('DB_USER'),
60 | 'password' => getenv('DB_PASSWORD'),
61 | 'charset' => 'utf8',
62 | 'collation' => 'utf8_unicode_ci',
63 | 'prefix' => '',
64 | ),
65 |
66 | 'pgsql' => array(
67 | 'driver' => 'pgsql',
68 | 'host' => 'localhost',
69 | 'database' => 'forge',
70 | 'username' => 'forge',
71 | 'password' => '',
72 | 'charset' => 'utf8',
73 | 'prefix' => '',
74 | 'schema' => 'public',
75 | ),
76 |
77 | 'sqlsrv' => array(
78 | 'driver' => 'sqlsrv',
79 | 'host' => 'localhost',
80 | 'database' => 'database',
81 | 'username' => 'root',
82 | 'password' => '',
83 | 'prefix' => '',
84 | ),
85 |
86 | ),
87 |
88 | /*
89 | |--------------------------------------------------------------------------
90 | | Migration Repository Table
91 | |--------------------------------------------------------------------------
92 | |
93 | | This table keeps track of all the migrations that have already run for
94 | | your application. Using this information, we can determine which of
95 | | the migrations on disk haven't actually been run in the database.
96 | |
97 | */
98 |
99 | 'migrations' => 'migrations',
100 |
101 | /*
102 | |--------------------------------------------------------------------------
103 | | Redis Databases
104 | |--------------------------------------------------------------------------
105 | |
106 | | Redis is an open source, fast, and advanced key-value store that also
107 | | provides a richer set of commands than a typical key-value systems
108 | | such as APC or Memcached. Laravel makes it easy to dig right in.
109 | |
110 | */
111 |
112 | 'redis' => array(
113 |
114 | 'cluster' => false,
115 |
116 | 'default' => array(
117 | 'host' => '127.0.0.1',
118 | 'port' => 6379,
119 | 'database' => 0,
120 | ),
121 |
122 | ),
123 |
124 | );
125 |
--------------------------------------------------------------------------------
/app/config/mail.php:
--------------------------------------------------------------------------------
1 | 'smtp',
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | SMTP Host Address
23 | |--------------------------------------------------------------------------
24 | |
25 | | Here you may provide the host address of the SMTP server used by your
26 | | applications. A default option is provided that is compatible with
27 | | the Mailgun mail service which will provide reliable deliveries.
28 | |
29 | */
30 |
31 | 'host' => 'smtp.mailgun.org',
32 |
33 | /*
34 | |--------------------------------------------------------------------------
35 | | SMTP Host Port
36 | |--------------------------------------------------------------------------
37 | |
38 | | This is the SMTP port used by your application to deliver e-mails to
39 | | users of the application. Like the host we have set this value to
40 | | stay compatible with the Mailgun e-mail application by default.
41 | |
42 | */
43 |
44 | 'port' => 587,
45 |
46 | /*
47 | |--------------------------------------------------------------------------
48 | | Global "From" Address
49 | |--------------------------------------------------------------------------
50 | |
51 | | You may wish for all e-mails sent by your application to be sent from
52 | | the same address. Here, you may specify a name and address that is
53 | | used globally for all e-mails that are sent by your application.
54 | |
55 | */
56 |
57 | 'from' => array('address' => null, 'name' => null),
58 |
59 | /*
60 | |--------------------------------------------------------------------------
61 | | E-Mail Encryption Protocol
62 | |--------------------------------------------------------------------------
63 | |
64 | | Here you may specify the encryption protocol that should be used when
65 | | the application send e-mail messages. A sensible default using the
66 | | transport layer security protocol should provide great security.
67 | |
68 | */
69 |
70 | 'encryption' => 'tls',
71 |
72 | /*
73 | |--------------------------------------------------------------------------
74 | | SMTP Server Username
75 | |--------------------------------------------------------------------------
76 | |
77 | | If your SMTP server requires a username for authentication, you should
78 | | set it here. This will get used to authenticate with your server on
79 | | connection. You may also set the "password" value below this one.
80 | |
81 | */
82 |
83 | 'username' => null,
84 |
85 | /*
86 | |--------------------------------------------------------------------------
87 | | SMTP Server Password
88 | |--------------------------------------------------------------------------
89 | |
90 | | Here you may set the password required by your SMTP server to send out
91 | | messages from your application. This will be given to the server on
92 | | connection so that the application will be able to send messages.
93 | |
94 | */
95 |
96 | 'password' => null,
97 |
98 | /*
99 | |--------------------------------------------------------------------------
100 | | Sendmail System Path
101 | |--------------------------------------------------------------------------
102 | |
103 | | When using the "sendmail" driver to send e-mails, we will need to know
104 | | the path to where Sendmail lives on this server. A default path has
105 | | been provided here, which will work well on most of your systems.
106 | |
107 | */
108 |
109 | 'sendmail' => '/usr/sbin/sendmail -bs',
110 |
111 | /*
112 | |--------------------------------------------------------------------------
113 | | Mail "Pretend"
114 | |--------------------------------------------------------------------------
115 | |
116 | | When this option is enabled, e-mail will not actually be sent over the
117 | | web and will instead be written to your application's logs files so
118 | | you may inspect the message. This is great for local development.
119 | |
120 | */
121 |
122 | 'pretend' => false,
123 |
124 | );
125 |
--------------------------------------------------------------------------------
/app/config/session.php:
--------------------------------------------------------------------------------
1 | 'memcached',
20 |
21 | /*
22 | |--------------------------------------------------------------------------
23 | | Session Lifetime
24 | |--------------------------------------------------------------------------
25 | |
26 | | Here you may specify the number of minutes that you wish the session
27 | | to be allowed to remain idle before it expires. If you want them
28 | | to immediately expire on the browser closing, set that option.
29 | |
30 | */
31 |
32 | 'lifetime' => 129600,
33 |
34 | 'expire_on_close' => false,
35 |
36 | /*
37 | |--------------------------------------------------------------------------
38 | | Session File Location
39 | |--------------------------------------------------------------------------
40 | |
41 | | When using the native session driver, we need a location where session
42 | | files may be stored. A default has been set for you but a different
43 | | location may be specified. This is only needed for file sessions.
44 | |
45 | */
46 |
47 | 'files' => storage_path().'/sessions',
48 |
49 | /*
50 | |--------------------------------------------------------------------------
51 | | Session Database Connection
52 | |--------------------------------------------------------------------------
53 | |
54 | | When using the "database" or "redis" session drivers, you may specify a
55 | | connection that should be used to manage these sessions. This should
56 | | correspond to a connection in your database configuration options.
57 | |
58 | */
59 |
60 | 'connection' => null,
61 |
62 | /*
63 | |--------------------------------------------------------------------------
64 | | Session Database Table
65 | |--------------------------------------------------------------------------
66 | |
67 | | When using the "database" session driver, you may specify the table we
68 | | should use to manage the sessions. Of course, a sensible default is
69 | | provided for you; however, you are free to change this as needed.
70 | |
71 | */
72 |
73 | 'table' => 'sessions',
74 |
75 | /*
76 | |--------------------------------------------------------------------------
77 | | Session Sweeping Lottery
78 | |--------------------------------------------------------------------------
79 | |
80 | | Some session drivers must manually sweep their storage location to get
81 | | rid of old sessions from storage. Here are the chances that it will
82 | | happen on a given request. By default, the odds are 2 out of 100.
83 | |
84 | */
85 |
86 | 'lottery' => array(2, 100),
87 |
88 | /*
89 | |--------------------------------------------------------------------------
90 | | Session Cookie Name
91 | |--------------------------------------------------------------------------
92 | |
93 | | Here you may change the name of the cookie used to identify a session
94 | | instance by ID. The name specified here will get used every time a
95 | | new session cookie is created by the framework for every driver.
96 | |
97 | */
98 |
99 | 'cookie' => 'get_your_vimrc_fu_on',
100 |
101 | /*
102 | |--------------------------------------------------------------------------
103 | | Session Cookie Path
104 | |--------------------------------------------------------------------------
105 | |
106 | | The session cookie path determines the path for which the cookie will
107 | | be regarded as available. Typically, this will be the root path of
108 | | your application but you are free to change this when necessary.
109 | |
110 | */
111 |
112 | 'path' => '/',
113 |
114 | /*
115 | |--------------------------------------------------------------------------
116 | | Session Cookie Domain
117 | |--------------------------------------------------------------------------
118 | |
119 | | Here you may change the domain of the cookie used to identify a session
120 | | in your application. This will determine which domains the cookie is
121 | | available to in your application. A sensible default has been set.
122 | |
123 | */
124 |
125 | 'domain' => null,
126 |
127 | /*
128 | |--------------------------------------------------------------------------
129 | | HTTPS Only Cookies
130 | |--------------------------------------------------------------------------
131 | |
132 | | By setting this option to true, session cookies will only be sent back
133 | | to the server if the browser has a HTTPS connection. This will keep
134 | | the cookie from being sent to you if it can not be done securely.
135 | |
136 | */
137 |
138 | 'secure' => false,
139 |
140 | );
141 |
--------------------------------------------------------------------------------
/app/Vimrcfu/Snippets/EloquentSnippetsRepository.php:
--------------------------------------------------------------------------------
1 | validator = $validator;
29 | $this->tagsRepository = $tagsRepository;
30 | }
31 |
32 | /**
33 | * @var string
34 | * @return mixed
35 | */
36 | public function snippetsWithCommentsAndUsersPaginated($order = null)
37 | {
38 | switch ($order)
39 | {
40 | case 'hot':
41 | return Snippet::select('snippets.*')
42 | ->rightJoin('votes', 'votes.snippet_id', '=', 'snippets.id')
43 | ->orderBy(DB::raw('sum(score)'), 'DESC')
44 | ->orderBy('snippets.created_at', 'DESC')
45 | ->groupBy('snippets.id')
46 | ->havingRaw('sum(score) > 1')
47 | ->with('comments', 'user')
48 | ->paginate(10);
49 | break;
50 | default:
51 | return Snippet::with('comments', 'user')->orderBy('id', 'DESC')->paginate(10);
52 | break;
53 | }
54 |
55 | }
56 |
57 | /**
58 | * @return mixed
59 | */
60 | public function snippetsForFeed()
61 | {
62 | return Snippet::with('user')->orderBy('id', 'desc')->take(20)->get();
63 | }
64 |
65 | /**
66 | * @return mixed
67 | */
68 | public function newSnippets()
69 | {
70 | return Snippet::with('comments', 'user')->orderBy('id', 'DESC')->take(5)->get();
71 | }
72 |
73 | /**
74 | * @return mixed
75 | */
76 | public function topSnippet()
77 | {
78 | return Cache::remember('topSnippet', 5, function ()
79 | {
80 | $topSnippetResult = DB::select(DB::raw('
81 | SELECT snippets.id, sum(votes.score) points FROM snippets
82 | JOIN votes ON snippets.id = votes.snippet_id
83 | GROUP BY snippets.id ORDER BY points DESC, snippets.id DESC LIMIT 1'
84 | ));
85 |
86 | return (isset($topSnippetResult[0])) ? $topSnippetResult[0] : new Snippet();
87 | });
88 | }
89 |
90 | /**
91 | * @return mixed
92 | */
93 | public function topCommented()
94 | {
95 | return Cache::remember('topComment', 5, function ()
96 | {
97 | $topCommentResult = DB::select(DB::raw('
98 | SELECT snippets.id, count(comments.id) comments_count FROM snippets
99 | JOIN comments ON snippets.id = comments.snippet_id
100 | GROUP BY snippet_id ORDER BY comments_count DESC LIMIT 1'
101 | ));
102 |
103 | return (isset($topCommentResult[0])) ? $topCommentResult[0] : new Comment();
104 | });
105 | }
106 |
107 | /**
108 | * @param array $input
109 | * @return mixed
110 | */
111 | public function create($input)
112 | {
113 | $this->validator->validate($input);
114 | $snippet = new Snippet();
115 | $snippet->title = $input['title'];
116 | $snippet->body = $input['body'];
117 | $snippet->description = $input['description'];
118 | $snippet->user_id = Auth::user()->id;
119 | $snippet->save();
120 |
121 | $this->tagsRepository->updateTags($snippet, $input['tags']);
122 |
123 | $vote = new Vote();
124 | $vote->user_id = Auth::user()->id;
125 | $vote->snippet_id = $snippet->id;
126 | $vote->score = 1;
127 | $vote->save();
128 |
129 | return $snippet;
130 | }
131 |
132 | /**
133 | * @param Vimrcfu\Snippets\Snippet $snippet
134 | * @param array $input
135 | * @return mixed
136 | */
137 | public function update(Snippet $snippet, $input)
138 | {
139 | $this->validator->validate($input);
140 |
141 | $snippet->title = $input['title'];
142 | $snippet->body = $input['body'];
143 | $snippet->description = $input['description'];
144 | $snippet->save();
145 |
146 | $this->tagsRepository->updateTags($snippet, $input['tags']);
147 |
148 | return $snippet;
149 | }
150 |
151 | /**
152 | * @param string $search
153 | * @return array
154 | */
155 | public function fulltextSearch($search) {
156 | // Need to use simplePaginate() here and then run
157 | // an extra count() query because Laravel 2.4's Paginator class
158 | // cannot determine the correct total number automatically in this case.
159 | $items = Snippet::whereRaw('MATCH(title,description,body) AGAINST(? IN BOOLEAN MODE)')
160 | ->select('*')
161 | ->addSelect( DB::raw('MATCH (title) AGAINST(?) title_relevance') )
162 | ->addSelect( DB::raw('MATCH (title,description,body) AGAINST (?) relevance') )
163 | ->setBindings([$search,$search,$search])
164 | ->orderBy('title_relevance', 'desc')
165 | ->orderBy('relevance', 'desc')
166 | ->with('comments', 'user')
167 | ->simplePaginate(10);
168 |
169 | $total = Snippet::whereRaw('MATCH(title,description,body) AGAINST(? IN BOOLEAN MODE)', [$search])->count();
170 |
171 | return [
172 | 'items' => $items,
173 | 'total' => $total
174 | ];
175 | }
176 |
177 | }
178 |
--------------------------------------------------------------------------------
/app/lang/en/validation.php:
--------------------------------------------------------------------------------
1 | "The :attribute must be accepted.",
17 | "active_url" => "The :attribute is not a valid URL.",
18 | "after" => "The :attribute must be a date after :date.",
19 | "alpha" => "The :attribute may only contain letters.",
20 | "alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.",
21 | "alpha_num" => "The :attribute may only contain letters and numbers.",
22 | "array" => "The :attribute must be an array.",
23 | "before" => "The :attribute must be a date before :date.",
24 | "between" => array(
25 | "numeric" => "The :attribute must be between :min and :max.",
26 | "file" => "The :attribute must be between :min and :max kilobytes.",
27 | "string" => "The :attribute must be between :min and :max characters.",
28 | "array" => "The :attribute must have between :min and :max items.",
29 | ),
30 | "boolean" => "The :attribute field must be true or false.",
31 | "confirmed" => "The :attribute confirmation does not match.",
32 | "date" => "The :attribute is not a valid date.",
33 | "date_format" => "The :attribute does not match the format :format.",
34 | "different" => "The :attribute and :other must be different.",
35 | "digits" => "The :attribute must be :digits digits.",
36 | "digits_between" => "The :attribute must be between :min and :max digits.",
37 | "email" => "The :attribute must be a valid email address.",
38 | "exists" => "The selected :attribute is invalid.",
39 | "image" => "The :attribute must be an image.",
40 | "in" => "The selected :attribute is invalid.",
41 | "integer" => "The :attribute must be an integer.",
42 | "ip" => "The :attribute must be a valid IP address.",
43 | "max" => array(
44 | "numeric" => "The :attribute may not be greater than :max.",
45 | "file" => "The :attribute may not be greater than :max kilobytes.",
46 | "string" => "The :attribute may not be greater than :max characters.",
47 | "array" => "The :attribute may not have more than :max items.",
48 | ),
49 | "mimes" => "The :attribute must be a file of type: :values.",
50 | "min" => array(
51 | "numeric" => "The :attribute must be at least :min.",
52 | "file" => "The :attribute must be at least :min kilobytes.",
53 | "string" => "The :attribute must be at least :min characters.",
54 | "array" => "The :attribute must have at least :min items.",
55 | ),
56 | "not_in" => "The selected :attribute is invalid.",
57 | "numeric" => "The :attribute must be a number.",
58 | "regex" => "The :attribute format is invalid.",
59 | "required" => "The :attribute field is required.",
60 | "required_if" => "The :attribute field is required when :other is :value.",
61 | "required_with" => "The :attribute field is required when :values is present.",
62 | "required_with_all" => "The :attribute field is required when :values is present.",
63 | "required_without" => "The :attribute field is required when :values is not present.",
64 | "required_without_all" => "The :attribute field is required when none of :values are present.",
65 | "same" => "The :attribute and :other must match.",
66 | "size" => array(
67 | "numeric" => "The :attribute must be :size.",
68 | "file" => "The :attribute must be :size kilobytes.",
69 | "string" => "The :attribute must be :size characters.",
70 | "array" => "The :attribute must contain :size items.",
71 | ),
72 | "unique" => "The :attribute has already been taken.",
73 | "url" => "The :attribute format is invalid.",
74 | "timezone" => "The :attribute must be a valid zone.",
75 |
76 | /*
77 | |--------------------------------------------------------------------------
78 | | Custom Validation Language Lines
79 | |--------------------------------------------------------------------------
80 | |
81 | | Here you may specify custom validation messages for attributes using the
82 | | convention "attribute.rule" to name the lines. This makes it quick to
83 | | specify a specific custom language line for a given attribute rule.
84 | |
85 | */
86 |
87 | 'custom' => array(
88 | 'attribute-name' => array(
89 | 'rule-name' => 'custom-message',
90 | ),
91 | ),
92 |
93 | /*
94 | |--------------------------------------------------------------------------
95 | | Custom Validation Attributes
96 | |--------------------------------------------------------------------------
97 | |
98 | | The following language lines are used to swap attribute place-holders
99 | | with something more reader friendly such as E-Mail Address instead
100 | | of "email". This simply helps us make messages a little cleaner.
101 | |
102 | */
103 |
104 | 'attributes' => array(),
105 |
106 | );
107 |
--------------------------------------------------------------------------------
/public/css/main.css:
--------------------------------------------------------------------------------
1 | body
2 | {
3 | padding-top: 50px;
4 | padding-bottom: 20px;
5 | }
6 |
7 | a
8 | {
9 | transition: all .2s ease-in;
10 | }
11 |
12 | a:hover, a:focus
13 | {
14 | color: #17467b;
15 | text-decoration: none;
16 | }
17 |
18 | a.navbar-brand
19 | {
20 | font-family: Courier, monospace;
21 | }
22 |
23 | .wow
24 | {
25 | visibility: hidden;
26 | }
27 |
28 | .jumbotron
29 | {
30 | background: url('../img/home_bg.png') no-repeat top left fixed;
31 | background-size: cover;
32 | color: white;
33 | }
34 |
35 | .jumbotron h1
36 | {
37 | letter-spacing: -3px;
38 | }
39 |
40 | .snippet-box
41 | {
42 | margin-bottom: 10px;
43 | min-height: 110px;
44 | }
45 |
46 | .snippet-box h3
47 | {
48 | margin-top: 0;
49 | word-wrap: break-word;
50 | -webkit-hyphens: auto;
51 | -moz-hyphens: auto;
52 | hyphens: auto;
53 | }
54 |
55 | textarea.snippet
56 | {
57 | font-family: "Courier";
58 | }
59 |
60 | .comment-box
61 | {
62 | padding: 10px 0;
63 | overflow: auto;
64 | }
65 |
66 | .comment-box:nth-child(odd)
67 | {
68 | background: rgba(28,120,220,.1);
69 | }
70 |
71 | .comment-box blockquote
72 | {
73 | font-size: 0.9em;
74 | }
75 |
76 | /* block code */
77 | .comment-box code
78 | {
79 | display: block;
80 | white-space: pre;
81 | overflow: auto;
82 | }
83 |
84 | /* inline code */
85 | .comment-box p code
86 | {
87 | display: inline;
88 | white-space: pre-line;
89 | }
90 |
91 | .comment-form
92 | {
93 | margin-bottom: 20px;
94 | }
95 |
96 | abbr
97 | {
98 | font-style: italic;
99 | }
100 |
101 | img.img-profile
102 | {
103 | max-width: 100px;
104 | max-height: 100px;
105 | float: left;
106 | margin-right: 10px;
107 | margin-bottom: 25px;
108 | }
109 |
110 | img.rounded
111 | {
112 | border: 5px solid #ddd;
113 | border-radius: 5em;
114 | }
115 |
116 | .score
117 | {
118 | margin-top: 21px;
119 | margin-bottom:10.5px;
120 | line-height: 1.1;
121 | font-size: 39px;
122 | font-family: "Source Sans Pro",Calibri,Candara,Arial,sans-serif;
123 | font-weight: 300;
124 | }
125 |
126 | .votelink:hover
127 | {
128 | cursor: text;
129 | color: #2780e3;
130 | }
131 |
132 | .dark
133 | {
134 | color: #999;
135 | }
136 |
137 | .dark:hover
138 | {
139 | cursor: pointer;
140 | color: #2780e3;
141 | }
142 |
143 | .hidden
144 | {
145 | position: absolute;
146 | left: -200em;
147 | }
148 |
149 | .toggle-visibility
150 | {
151 | cursor: pointer;
152 | border-bottom: 1px dotted;
153 | }
154 |
155 | kbd
156 | {
157 | color: #000;
158 | background: #eee;
159 | border-style: solid;
160 | border-color: #ccc #aaa #888 #bbb;
161 | padding: .1em .6em;
162 | border: 1px solid #ccc;
163 | font-size: 11px;
164 | background-color: #f7f7f7;
165 | color: #333;
166 | -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
167 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
168 | box-shadow: 0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
169 | border-radius: 2px;
170 | display: inline-block;
171 | margin: 0 .1em;
172 | text-shadow: 0 1px 0 #fff;
173 | line-height: 1.4;
174 | white-space: nowrap;
175 | }
176 |
177 | .bootstrap-tagsinput
178 | {
179 | background-color: #fff;
180 | border: 1px solid #ccc;
181 | box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
182 | display: block;
183 | color: #333;
184 | vertical-align: middle;
185 | border-radius: 0px;
186 | max-width: 100%;
187 | cursor: text;
188 | padding: 10px 16px;
189 | -webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
190 | -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
191 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
192 | }
193 |
194 | .bootstrap-tagsinput.focus
195 | {
196 | border-color: #66afe9;
197 | outline: 0;
198 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);
199 | box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);
200 | }
201 |
202 | .bootstrap-tagsinput input
203 | {
204 | border: none;
205 | box-shadow: none;
206 | outline: none;
207 | background-color: transparent;
208 | margin: 0;
209 | width: auto !important;
210 | max-width: inherit;
211 | }
212 |
213 | .bootstrap-tagsinput input:focus
214 | {
215 | border: none;
216 | box-shadow: none;
217 | }
218 |
219 | .bootstrap-tagsinput .tag
220 | {
221 | margin-right: 2px;
222 | }
223 |
224 | .bootstrap-tagsinput .tag [data-role="remove"]
225 | {
226 | margin-left: 8px;
227 | cursor: pointer;
228 | }
229 |
230 | .bootstrap-tagsinput .tag [data-role="remove"]:after
231 | {
232 | content: "x";
233 | padding: 0px 2px;
234 | }
235 |
236 | .twitter-typeahead .tt-query,
237 | .twitter-typeahead .tt-hint
238 | {
239 | margin-bottom: 0;
240 | }
241 |
242 | .twitter-typeahead .tt-hint
243 | {
244 | display: none;
245 | }
246 |
247 | .tt-input
248 | {
249 | width: auto;
250 | }
251 |
252 | .tt-dropdown-menu
253 | {
254 | position: absolute;
255 | top: 100%;
256 | left: 0;
257 | z-index: 1000;
258 | display: none;
259 | float: left;
260 | min-width: 160px;
261 | padding: 5px 0;
262 | margin: 2px 0 0;
263 | list-style: none;
264 | background-color: #fff;
265 | border: 1px solid #ccc;
266 | border: 1px solid rgba(0, 0, 0, 0.15);
267 | border-radius: 0px;
268 | -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
269 | box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
270 | background-clip: padding-box;
271 | }
272 |
273 | .tt-suggestion > p
274 | {
275 | display: block;
276 | padding: 3px 20px;
277 | clear: both;
278 | font-weight: normal;
279 | line-height: 1.428571429;
280 | color: #333333;
281 | white-space: nowrap;
282 | cursor: pointer;
283 | margin: 0;
284 | }
285 |
286 | .tt-suggestion > p:hover,
287 | .tt-suggestion > p:focus,
288 | .tt-suggestion.tt-cursor p
289 | {
290 | color: #ffffff;
291 | text-decoration: none;
292 | outline: 0;
293 | background-color: #1a6ecc;
294 | }
295 |
--------------------------------------------------------------------------------
/public/js/vendor/wow.min.js:
--------------------------------------------------------------------------------
1 | /*! WOW - v1.0.2 - 2014-09-24
2 | * Copyright (c) 2014 Matthieu Aussaguel; Licensed MIT */(function(){var a,b,c,d,e,f=function(a,b){return function(){return a.apply(b,arguments)}},g=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};b=function(){function a(){}return a.prototype.extend=function(a,b){var c,d;for(c in b)d=b[c],null==a[c]&&(a[c]=d);return a},a.prototype.isMobile=function(a){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(a)},a.prototype.addEvent=function(a,b,c){return null!=a.addEventListener?a.addEventListener(b,c,!1):null!=a.attachEvent?a.attachEvent("on"+b,c):a[b]=c},a.prototype.removeEvent=function(a,b,c){return null!=a.removeEventListener?a.removeEventListener(b,c,!1):null!=a.detachEvent?a.detachEvent("on"+b,c):delete a[b]},a.prototype.innerHeight=function(){return"innerHeight"in window?window.innerHeight:document.documentElement.clientHeight},a}(),c=this.WeakMap||this.MozWeakMap||(c=function(){function a(){this.keys=[],this.values=[]}return a.prototype.get=function(a){var b,c,d,e,f;for(f=this.keys,b=d=0,e=f.length;e>d;b=++d)if(c=f[b],c===a)return this.values[b]},a.prototype.set=function(a,b){var c,d,e,f,g;for(g=this.keys,c=e=0,f=g.length;f>e;c=++e)if(d=g[c],d===a)return void(this.values[c]=b);return this.keys.push(a),this.values.push(b)},a}()),a=this.MutationObserver||this.WebkitMutationObserver||this.MozMutationObserver||(a=function(){function a(){"undefined"!=typeof console&&null!==console&&console.warn("MutationObserver is not supported by your browser."),"undefined"!=typeof console&&null!==console&&console.warn("WOW.js cannot detect dom mutations, please call .sync() after loading new content.")}return a.notSupported=!0,a.prototype.observe=function(){},a}()),d=this.getComputedStyle||function(a){return this.getPropertyValue=function(b){var c;return"float"===b&&(b="styleFloat"),e.test(b)&&b.replace(e,function(a,b){return b.toUpperCase()}),(null!=(c=a.currentStyle)?c[b]:void 0)||null},this},e=/(\-([a-z]){1})/g,this.WOW=function(){function e(a){null==a&&(a={}),this.scrollCallback=f(this.scrollCallback,this),this.scrollHandler=f(this.scrollHandler,this),this.start=f(this.start,this),this.scrolled=!0,this.config=this.util().extend(a,this.defaults),this.animationNameCache=new c}return e.prototype.defaults={boxClass:"wow",animateClass:"animated",offset:0,mobile:!0,live:!0},e.prototype.init=function(){var a;return this.element=window.document.documentElement,"interactive"===(a=document.readyState)||"complete"===a?this.start():this.util().addEvent(document,"DOMContentLoaded",this.start),this.finished=[]},e.prototype.start=function(){var b,c,d,e;if(this.stopped=!1,this.boxes=function(){var a,c,d,e;for(d=this.element.querySelectorAll("."+this.config.boxClass),e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.all=function(){var a,c,d,e;for(d=this.boxes,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.boxes.length)if(this.disabled())this.resetStyle();else{for(e=this.boxes,c=0,d=e.length;d>c;c++)b=e[c],this.applyStyle(b,!0);this.util().addEvent(window,"scroll",this.scrollHandler),this.util().addEvent(window,"resize",this.scrollHandler),this.interval=setInterval(this.scrollCallback,50)}return this.config.live?new a(function(a){return function(b){var c,d,e,f,g;for(g=[],e=0,f=b.length;f>e;e++)d=b[e],g.push(function(){var a,b,e,f;for(e=d.addedNodes||[],f=[],a=0,b=e.length;b>a;a++)c=e[a],f.push(this.doSync(c));return f}.call(a));return g}}(this)).observe(document.body,{childList:!0,subtree:!0}):void 0},e.prototype.stop=function(){return this.stopped=!0,this.util().removeEvent(window,"scroll",this.scrollHandler),this.util().removeEvent(window,"resize",this.scrollHandler),null!=this.interval?clearInterval(this.interval):void 0},e.prototype.sync=function(){return a.notSupported?this.doSync(this.element):void 0},e.prototype.doSync=function(a){var b,c,d,e,f;if(null==a&&(a=this.element),1===a.nodeType){for(a=a.parentNode||a,e=a.querySelectorAll("."+this.config.boxClass),f=[],c=0,d=e.length;d>c;c++)b=e[c],g.call(this.all,b)<0?(this.boxes.push(b),this.all.push(b),this.stopped||this.disabled()?this.resetStyle():this.applyStyle(b,!0),f.push(this.scrolled=!0)):f.push(void 0);return f}},e.prototype.show=function(a){return this.applyStyle(a),a.className=""+a.className+" "+this.config.animateClass},e.prototype.applyStyle=function(a,b){var c,d,e;return d=a.getAttribute("data-wow-duration"),c=a.getAttribute("data-wow-delay"),e=a.getAttribute("data-wow-iteration"),this.animate(function(f){return function(){return f.customStyle(a,b,d,c,e)}}(this))},e.prototype.animate=function(){return"requestAnimationFrame"in window?function(a){return window.requestAnimationFrame(a)}:function(a){return a()}}(),e.prototype.resetStyle=function(){var a,b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.style.visibility="visible");return e},e.prototype.customStyle=function(a,b,c,d,e){return b&&this.cacheAnimationName(a),a.style.visibility=b?"hidden":"visible",c&&this.vendorSet(a.style,{animationDuration:c}),d&&this.vendorSet(a.style,{animationDelay:d}),e&&this.vendorSet(a.style,{animationIterationCount:e}),this.vendorSet(a.style,{animationName:b?"none":this.cachedAnimationName(a)}),a},e.prototype.vendors=["moz","webkit"],e.prototype.vendorSet=function(a,b){var c,d,e,f;f=[];for(c in b)d=b[c],a[""+c]=d,f.push(function(){var b,f,g,h;for(g=this.vendors,h=[],b=0,f=g.length;f>b;b++)e=g[b],h.push(a[""+e+c.charAt(0).toUpperCase()+c.substr(1)]=d);return h}.call(this));return f},e.prototype.vendorCSS=function(a,b){var c,e,f,g,h,i;for(e=d(a),c=e.getPropertyCSSValue(b),i=this.vendors,g=0,h=i.length;h>g;g++)f=i[g],c=c||e.getPropertyCSSValue("-"+f+"-"+b);return c},e.prototype.animationName=function(a){var b;try{b=this.vendorCSS(a,"animation-name").cssText}catch(c){b=d(a).getPropertyValue("animation-name")}return"none"===b?"":b},e.prototype.cacheAnimationName=function(a){return this.animationNameCache.set(a,this.animationName(a))},e.prototype.cachedAnimationName=function(a){return this.animationNameCache.get(a)},e.prototype.scrollHandler=function(){return this.scrolled=!0},e.prototype.scrollCallback=function(){var a;return!this.scrolled||(this.scrolled=!1,this.boxes=function(){var b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],a&&(this.isVisible(a)?this.show(a):e.push(a));return e}.call(this),this.boxes.length||this.config.live)?void 0:this.stop()},e.prototype.offsetTop=function(a){for(var b;void 0===a.offsetTop;)a=a.parentNode;for(b=a.offsetTop;a=a.offsetParent;)b+=a.offsetTop;return b},e.prototype.isVisible=function(a){var b,c,d,e,f;return c=a.getAttribute("data-wow-offset")||this.config.offset,f=window.pageYOffset,e=f+Math.min(this.element.clientHeight,this.util().innerHeight())-c,d=this.offsetTop(a),b=d+a.clientHeight,e>=d&&b>=f},e.prototype.util=function(){return null!=this._util?this._util:this._util=new b},e.prototype.disabled=function(){return!this.config.mobile&&this.util().isMobile(navigator.userAgent)},e}()}).call(this);
--------------------------------------------------------------------------------
/public/js/vendor/bootstrap-tagsinput.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * bootstrap-tagsinput v0.4.2 by Tim Schlechter
3 | *
4 | */
5 |
6 | !function(a){"use strict";function b(b,c){this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('
'),this.$input=a(' ').appendTo(this.$container),this.$element.after(this.$container);var d=(this.inputSize<3?3:this.inputSize)+"em";this.$input.get(0).style.cssText="width: "+d+" !important;",this.build(c)}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?i.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}function g(b,c){var d=!1;return a.each(c,function(a,c){if("number"==typeof c&&b.which===c)return d=!0,!1;if(b.which===c.which){var e=!c.hasOwnProperty("altKey")||b.altKey===c.altKey,f=!c.hasOwnProperty("shiftKey")||b.shiftKey===c.shiftKey,g=!c.hasOwnProperty("ctrlKey")||b.ctrlKey===c.ctrlKey;if(e&&f&&g)return d=!0,!1}}),d}var h={tagClass:function(){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},freeInput:!0,addOnBlur:!0,maxTags:void 0,maxChars:void 0,confirmKeys:[13,44],onTagExists:function(a,b){b.hide().fadeIn()},trimValue:!1,allowDuplicates:!1};b.prototype={constructor:b,add:function(b,c){var d=this;if(!(d.options.maxTags&&d.itemsArray.length>=d.options.maxTags||b!==!1&&!b)){if("string"==typeof b&&d.options.trimValue&&(b=a.trim(b)),"object"==typeof b&&!d.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(d.isSelect&&!d.multiple&&d.itemsArray.length>0&&d.remove(d.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var f=b.split(",");if(f.length>1){for(var g=0;gd.options.maxInputLength)){var l=a.Event("beforeItemAdd",{item:b,cancel:!1});if(d.$element.trigger(l),!l.cancel){d.itemsArray.push(b);var m=a(''+e(i)+' ');if(m.data("item",b),d.findInputWrapper().before(m),m.after(" "),d.isSelect&&!a('option[value="'+encodeURIComponent(h)+'"]',d.$element)[0]){var n=a(""+e(i)+" ");n.data("item",b),n.attr("value",h),d.$element.append(n)}c||d.pushVal(),(d.options.maxTags===d.itemsArray.length||d.items().toString().length===d.options.maxInputLength)&&d.$container.addClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemAdded",{item:b}))}}}else if(d.options.onTagExists){var o=a(".tag",d.$container).filter(function(){return a(this).data("item")===k});d.options.onTagExists(b,o)}}}},remove:function(b,c){var d=this;if(d.objectItems&&(b="object"==typeof b?a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==d.options.itemValue(b)}):a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==b}),b=b[b.length-1]),b){var e=a.Event("beforeItemRemove",{item:b,cancel:!1});if(d.$element.trigger(e),e.cancel)return;a(".tag",d.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",d.$element).filter(function(){return a(this).data("item")===b}).remove(),-1!==a.inArray(b,d.itemsArray)&&d.itemsArray.splice(a.inArray(b,d.itemsArray),1)}c||d.pushVal(),d.options.maxTags>d.itemsArray.length&&d.$container.removeClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemRemoved",{item:b}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;if(e.options=a.extend({},h,b),e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),d(e.options,"tagClass"),e.options.typeahead){var i=e.options.typeahead||{};d(i,"source"),e.$input.typeahead(a.extend({},i,{source:function(b,c){function d(a){for(var b=[],d=0;d$1")}}))}if(e.options.typeaheadjs){var j=e.options.typeaheadjs||{};e.$input.typeahead(null,j).on("typeahead:selected",a.proxy(function(a,b){e.add(j.valueKey?b[j.valueKey]:b),e.$input.typeahead("val","")},e))}e.$container.on("click",a.proxy(function(){e.$element.attr("disabled")||e.$input.removeAttr("disabled"),e.$input.focus()},e)),e.options.addOnBlur&&e.options.freeInput&&e.$input.on("focusout",a.proxy(function(){0===a(".typeahead, .twitter-typeahead",e.$container).length&&(e.add(e.$input.val()),e.$input.val(""))},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus())}{var k=c.val().length;Math.ceil(k/5)}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("keypress","input",a.proxy(function(b){var c=a(b.target);if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");var d=c.val(),f=e.options.maxChars&&d.length>=e.options.maxChars;e.options.freeInput&&(g(b,e.options.confirmKeys)||f)&&(e.add(f?d.substr(0,e.options.maxChars):d),c.val(""),b.preventDefault());{var h=c.val().length;Math.ceil(h/5)}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.$element.attr("disabled")||e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===h.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d){var e=[];return this.each(function(){var f=a(this).data("tagsinput");if(f)if(c||d){if(void 0!==f[c]){var g=f[c](d);void 0!==g&&e.push(g)}}else e.push(f);else f=new b(this,c),a(this).data("tagsinput",f),e.push(f),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?e.length>1?e:e[0]:e},a.fn.tagsinput.Constructor=b;var i=a("
");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery);
7 | //# sourceMappingURL=bootstrap-tagsinput.min.js.map
--------------------------------------------------------------------------------
/app/config/app.php:
--------------------------------------------------------------------------------
1 | false,
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Application URL
21 | |--------------------------------------------------------------------------
22 | |
23 | | This URL is used by the console to properly generate URLs when using
24 | | the Artisan command line tool. You should set this to the root of
25 | | your application so that it is used when running Artisan tasks.
26 | |
27 | */
28 |
29 | 'url' => 'http://vimrcfu.com',
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Application Timezone
34 | |--------------------------------------------------------------------------
35 | |
36 | | Here you may specify the default timezone for your application, which
37 | | will be used by the PHP date and date-time functions. We have gone
38 | | ahead and set this to a sensible default for you out of the box.
39 | |
40 | */
41 |
42 | 'timezone' => 'UTC',
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Application Locale Configuration
47 | |--------------------------------------------------------------------------
48 | |
49 | | The application locale determines the default locale that will be used
50 | | by the translation service provider. You are free to set this value
51 | | to any of the locales which will be supported by the application.
52 | |
53 | */
54 |
55 | 'locale' => 'en',
56 |
57 | /*
58 | |--------------------------------------------------------------------------
59 | | Application Fallback Locale
60 | |--------------------------------------------------------------------------
61 | |
62 | | The fallback locale determines the locale to use when the current one
63 | | is not available. You may change the value to correspond to any of
64 | | the language folders that are provided through your application.
65 | |
66 | */
67 |
68 | 'fallback_locale' => 'en',
69 |
70 | /*
71 | |--------------------------------------------------------------------------
72 | | Encryption Key
73 | |--------------------------------------------------------------------------
74 | |
75 | | This key is used by the Illuminate encrypter service and should be set
76 | | to a random, 32 character string, otherwise these encrypted strings
77 | | will not be safe. Please do this before deploying an application!
78 | |
79 | */
80 |
81 | 'key' => getenv('APP_KEY'),
82 |
83 | 'cipher' => MCRYPT_RIJNDAEL_128,
84 |
85 | /*
86 | |--------------------------------------------------------------------------
87 | | Autoloaded Service Providers
88 | |--------------------------------------------------------------------------
89 | |
90 | | The service providers listed here will be automatically loaded on the
91 | | request to your application. Feel free to add your own services to
92 | | this array to grant expanded functionality to your applications.
93 | |
94 | */
95 |
96 | 'providers' => array(
97 |
98 | 'Illuminate\Foundation\Providers\ArtisanServiceProvider',
99 | 'Illuminate\Auth\AuthServiceProvider',
100 | 'Illuminate\Cache\CacheServiceProvider',
101 | 'Illuminate\Session\CommandsServiceProvider',
102 | 'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
103 | 'Illuminate\Routing\ControllerServiceProvider',
104 | 'Illuminate\Cookie\CookieServiceProvider',
105 | 'Illuminate\Database\DatabaseServiceProvider',
106 | 'Illuminate\Encryption\EncryptionServiceProvider',
107 | 'Illuminate\Filesystem\FilesystemServiceProvider',
108 | 'Illuminate\Hashing\HashServiceProvider',
109 | 'Illuminate\Html\HtmlServiceProvider',
110 | 'Illuminate\Log\LogServiceProvider',
111 | 'Illuminate\Mail\MailServiceProvider',
112 | 'Illuminate\Database\MigrationServiceProvider',
113 | 'Illuminate\Pagination\PaginationServiceProvider',
114 | 'Illuminate\Queue\QueueServiceProvider',
115 | 'Illuminate\Redis\RedisServiceProvider',
116 | 'Illuminate\Remote\RemoteServiceProvider',
117 | 'Illuminate\Auth\Reminders\ReminderServiceProvider',
118 | 'Illuminate\Database\SeedServiceProvider',
119 | 'Illuminate\Session\SessionServiceProvider',
120 | 'Illuminate\Translation\TranslationServiceProvider',
121 | 'Illuminate\Validation\ValidationServiceProvider',
122 | 'Illuminate\View\ViewServiceProvider',
123 | 'Illuminate\Workbench\WorkbenchServiceProvider',
124 | 'Artdarek\OAuth\OAuthServiceProvider',
125 | 'Vimrcfu\Providers\CoreServiceProvider',
126 | 'Vimrcfu\Providers\PersistenceServiceProvider',
127 |
128 | ),
129 |
130 | /*
131 | |--------------------------------------------------------------------------
132 | | Service Provider Manifest
133 | |--------------------------------------------------------------------------
134 | |
135 | | The service provider manifest is used by Laravel to lazy load service
136 | | providers which are not needed for each request, as well to keep a
137 | | list of all of the services. Here, you may set its storage spot.
138 | |
139 | */
140 |
141 | 'manifest' => storage_path().'/meta',
142 |
143 | /*
144 | |--------------------------------------------------------------------------
145 | | Class Aliases
146 | |--------------------------------------------------------------------------
147 | |
148 | | This array of class aliases will be registered when this application
149 | | is started. However, feel free to register as many as you wish as
150 | | the aliases are "lazy" loaded so they don't hinder performance.
151 | |
152 | */
153 |
154 | 'aliases' => array(
155 |
156 | 'App' => 'Illuminate\Support\Facades\App',
157 | 'Artisan' => 'Illuminate\Support\Facades\Artisan',
158 | 'Auth' => 'Illuminate\Support\Facades\Auth',
159 | 'Blade' => 'Illuminate\Support\Facades\Blade',
160 | 'Cache' => 'Illuminate\Support\Facades\Cache',
161 | 'ClassLoader' => 'Illuminate\Support\ClassLoader',
162 | 'Config' => 'Illuminate\Support\Facades\Config',
163 | 'Controller' => 'Illuminate\Routing\Controller',
164 | 'Cookie' => 'Illuminate\Support\Facades\Cookie',
165 | 'Crypt' => 'Illuminate\Support\Facades\Crypt',
166 | 'DB' => 'Illuminate\Support\Facades\DB',
167 | 'Eloquent' => 'Illuminate\Database\Eloquent\Model',
168 | 'Event' => 'Illuminate\Support\Facades\Event',
169 | 'File' => 'Illuminate\Support\Facades\File',
170 | 'Form' => 'Illuminate\Support\Facades\Form',
171 | 'Hash' => 'Illuminate\Support\Facades\Hash',
172 | 'HTML' => 'Illuminate\Support\Facades\HTML',
173 | 'Input' => 'Illuminate\Support\Facades\Input',
174 | 'Lang' => 'Illuminate\Support\Facades\Lang',
175 | 'Log' => 'Illuminate\Support\Facades\Log',
176 | 'Mail' => 'Illuminate\Support\Facades\Mail',
177 | 'Paginator' => 'Illuminate\Support\Facades\Paginator',
178 | 'Password' => 'Illuminate\Support\Facades\Password',
179 | 'Queue' => 'Illuminate\Support\Facades\Queue',
180 | 'Redirect' => 'Illuminate\Support\Facades\Redirect',
181 | 'Redis' => 'Illuminate\Support\Facades\Redis',
182 | 'Request' => 'Illuminate\Support\Facades\Request',
183 | 'Response' => 'Illuminate\Support\Facades\Response',
184 | 'Route' => 'Illuminate\Support\Facades\Route',
185 | 'Schema' => 'Illuminate\Support\Facades\Schema',
186 | 'Seeder' => 'Illuminate\Database\Seeder',
187 | 'Session' => 'Illuminate\Support\Facades\Session',
188 | 'SoftDeletingTrait' => 'Illuminate\Database\Eloquent\SoftDeletingTrait',
189 | 'SSH' => 'Illuminate\Support\Facades\SSH',
190 | 'Str' => 'Illuminate\Support\Str',
191 | 'URL' => 'Illuminate\Support\Facades\URL',
192 | 'Validator' => 'Illuminate\Support\Facades\Validator',
193 | 'View' => 'Illuminate\Support\Facades\View',
194 | 'OAuth' => 'Artdarek\OAuth\Facade\OAuth',
195 | 'Text' => 'Vimrcfu\Facades\TextFacade',
196 |
197 | ),
198 |
199 | );
200 |
--------------------------------------------------------------------------------
/public/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.1.1 (http://getbootstrap.com)
3 | * Copyright 2011-2014 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */
6 |
7 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
--------------------------------------------------------------------------------
{{ $comment->user->name }} 7 | 8 | {{ $comment->created_at->diffForHumans() }} 9 | @if(Auth::check() && Auth::user()->id == $comment->user_id) 10 | [edit] 11 | @endif 12 | 13 | @if($comment->created_at != $comment->updated_at && $comment->created_at->diffInMinutes($comment->updated_at) > 5) 14 | ✎ 15 | @endif 16 |
17 | {{ Text::render($comment->body) }} 18 |