Laravel Shortcodes

WordPress based Shortcodes for Laravel 5.x with shared variables, debugbar integration, flexible configuration and other useful features.

Github: https://github.com/vedmant/laravel-shortcodes

Build powerful and simple layouts using shortcodes in the content or views like this:

[b]Bold text[/b]
[row]
  [col md=8]
     [posts_list types="post,gallery" show_tags="yes"]
  [/col]
  [col md=4]
     [poll id="1"]
     [user_info username="test_user" website="mywebsite.com" active="yes"]
     [last_free_post title="Free Posts"]
  [/col]
[/row]

Installation

Via Composer

$ composer require vedmant/laravel-shortcodes

This package supports Laravel Auto-Discover and will be discovered automatically.

For Laravel version before 5.5 please add the Vedmant\LaravelShortcodes\LaravelShortcodesServiceProvider::class to the providers array in config/app.php. And optionally ‘Shortcodes’ => Vedmant\LaravelShortcodes\Facades\Shortcodes::class, to aliases.

Configuraton

Publish configuration.

php artisan vendor:publish --tag=shortcodes

Usage

Shortcode class

Shortcode class should extend abstract \Vedmant\LaravelShortcodes\Shortcode class.

This packages adds make:shortcode artisan command:

php artisan make:shortcode PostsListShortcode

It will generate a shortcode class in the app/Shortcodes folder by default.

Register shortcodes

You can use AppServiceProvider boot method to register all needed shortcodes.

Using shortcode class:

Shortcodes::add('b', BShortcode::class);

Using shortcode classes in array, preferable for lots of shortcodes:

Shortcodes::add([
   'a' => AShortcode::class,
   'b' => BShortcode::class,
]);

Using closure:

Shortcodes::add('test', function ($atts, $content, $tag, $manager) {
   return new HtmlString('<strong>some test shortcode</strong>');
});

Rendering shortcodes

By default this packages extends View to parse all shortcodes during views rendering. This feature can be disabled in the config file.

Also to enable / disable rendering shortcodes for specific view you can use:

view('some-view')->withShortcodes(); // Or view('some-view')->withoutShortcodes();

To render shortcodes manually use:

{{ Shortcodes::render('[b]bold[/b]') }}

Shared attributes

YOccasionally, you may need to share a piece of data with all shortcodes that are rendered by your application. You may do so using the shortode facade’s share method. Typically, you should place calls to share in the controller, or within a service provider’s boot method.

Shortcodes::share('post', $post);

Then you can get share attributes in the shortcode class:

$post = $this->shared('post'); $allShared = $this->shared();

Comma separated values (array attributes)

If you need to pass an array to a shortcode, you can pass values separated by comma:

[posts_list ids="1,2,3"]

Then in render function you can parse this attribute using build in method:

$ids = $this->parseCommaSeparated($atts['ids']);

Edit configuration file as needed.

Integration with Laravel Debugbar

This packages supports Laravel Debugbar. Integration can be disabled in the config file if needed.

This project is fully free to use for any purpose and licensed under MIT License.

Sample Single Page Application (SPA) using Laravel 5 & Vue2 + Vuex + Vue-Router

Not to long ago I implemented a sample Single Page Application using Laravel 5 and Vue2 + Vuex + Vue-Router.

Today I decided to make it public and share my experience with others.

The project is basically a simple Running Tracker, where you can add your running entries and see your performance during some period of time.

Main features

  • Fully separate Backend and Frontend
  • Authentication based on Laravel Passport
  • List pages with filters and CRUD editing
  • Admin panel
  • Simple widgets
  • Simple reports
  • Full Phpunit test coverage
  • Sample E2E tests using Nightwatch and Cypress

Includes

Other Features

  • Front page
  • Authentication (registration, login, logout, throttle)
  • Users roles: administrator (all access), manager (manage records)
  • User dashborad with widgets and charts
  • Entries list with filter by date (list, show, edit, delete, create)
  • Report page with chart
  • User profile page
  • Admin dashboard with widgets
  • Users admin (list, show, edit, delete, create)
  • Entries admin (list, show, edit, delete, create)
  • Global loader for all requests with small delay

GitHub Link

Demo

Use login: [email protected] and password: 123456

This project is fully free to use for any purpose and licenced under MIT License.

Testing emails with Laravel

Reliability of emails subsystem is essential for current web applications, but testing emails is not as easy at it looks at first glance. Laravel doesn’t provide a good solution for testing emails out of the box, so after a bit of Googling I come up with following solution for testing emails.

Helper

Basic idea is build on attaching event listener to Swift emails package, for this I extended base class Swift_Events_EventListener that takes as parameter our test case.

/**
 * Class TestingMailEventListener
 *
 * @package Tests
 */
class TestingMailEventListener implements Swift_Events_EventListener
{
    protected $test;

    /**
     * TestingMailEventListener constructor.
     *
     * @param $test
     */
    public function __construct($test)
    {
        $this->test = $test;
    }

    /**
     * Before email sent
     * 
     * @param Swift_Events_SendEvent $event
     */
    public function beforeSendPerformed(Swift_Events_SendEvent $event)
    {
        $this->test->addEmail($event->getMessage());
    }
}

Then I created a Trait with following method:

/**
 * Trait TracksEmails
 *
 * @package Tests
 */
trait TracksEmails
{
    /**
     * Delivered emails.
     * @var array
     */
    protected $emails = [];

    /**
     * Register a listener for new emails.
     *
     * @before
     */
    public function setUpMailTracking()
    {
        Mail::getSwiftMailer()
            ->registerPlugin(new TestingMailEventListener($this));
    }
...

Which registers event listener and collects all emails sent with Swift.

Having this done it’s easy to check whether particular email was sent, I also added bunch of helpers to make it easier:

/**
 * Assert that at least one email was sent.
 * @return $this
 */
protected function seeEmailWasSent()

/**
 * Assert that the given number of emails were sent.
 *
 * @param integer $count
 * @return $this
 */
protected function seeEmailsSent($count)

/**
 * Assert that the last email's body contains the given text.
 *
 * @param string $excerpt
 * @param Swift_Mime_Message $message
 * @return $this
 */
protected function seeEmailContains($excerpt, Swift_Mime_Message $message = null)
...

And several more.

Here you can see full helper trait code click.

Usage

Usage of this helper is quite simple, here is simple example:

public function testEmail()
{
    \Mail::raw('Some content', function (Message $message) {
        $message->from('[email protected]', 'Laravel');
        $message->to('[email protected]');
    });

    $this->seeEmailWasSent()
        ->seeEmailTo('[email protected]')
        ->seeEmailContains('Some content');
}

And a bit more complex example of how I test my password reset form:

public function testPasswordReset()
{
    $user = $this->makeUser();

    Event::listen(NotificationSent::class, function (NotificationSent $notification) use ($user) {
        self::$token = $notification->notification->token;
        $this->seeEmailWasSent()
            ->seeEmailTo($user->Login)
            ->seeEmailContains(self::$token);
    });

    $this->visitRoute('password.request')
        ->assertResponseOk()
        ->type($user->Login, 'email')
        ->press('Reset')
        ->assertResponseOk()
        ->see(trans('passwords.sent'))
        ->seeInDatabase('password_resets', ['email' => $user->Login]);

    $this->visitRoute('password.reset', ['token' => self::$token])
        ->assertResponseOk()
        ->type($user->Login, 'email')
        ->type('123123', 'password')
        ->type('123123', 'password_confirmation')
        ->press('Reset Password')
        ->assertResponseOk()
        ->seeRouteIs('dashboard');

    $this->assertTrue($this->isAuthenticated());

    $this->assertTrue(app('hash')->check('123123', $user->fresh()->Password));
}

In this example I used events listener to listen for notification to check if sent token is the correct one.

Currently there are some probably better alternatives for testing emails with Laravel, like this one tightenco/mailthief.

MS SQL on Vagrant Ubuntu Homestead box for development on Laravel

Hi everyone!

Recently I had a chance to setup and successfully run development environment with Microsoft SQL Server on Laravel’s Homestead Vagrant box. I used Homestead installation per project. And here is how I’ve done it.

Prepare Homestead box

First step is to install Homestead for a project:

composer require laravel/homestead --dev
php vendor/bin/homestead make

Then you need to change Homestead.yaml file.

Firstly, memory limit have to be changed to 4096: memory: 4096

Then hostname: hostname: mysite.dev

And probably name for convenience: ‘name: mysite.dev’

In sites section make sure that you have configuration like this:

sites:
    - map: mysite.dev
      to: "/home/vagrant/project/public"

Then download and install Vagrant box

vagrant up

And add to hosts file domain for a this box 192.168.10.10 mysite.dev.

Install, setup and import database

To setup database login to Vagrant box

vagrant ssh

Install MS SQL server and tools:

curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/mssql-server.list | sudo tee /etc/apt/sources.list.d/mssql-server.list
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list

sudo apt-get update
sudo apt-get install -y mssql-server
sudo apt-get install -y mssql-tools unixodbc-dev

sudo ln -sfn /opt/mssql-tools/bin/sqlcmd-13.0.1.0 /usr/bin/sqlcmd
sudo ln -sfn /opt/mssql-tools/bin/bcp-13.0.1.0 /usr/bin/bcp

Then run initial MS SQL setup script

sudo /opt/mssql/bin/mssql-conf setup

Use password “Secret123”, start server and enable starting on boot

Then it will require to install Sybase php extension

sudo apt-get install -y php7.1-sybase

When it will be updating some packages, select to keep the local version of config files on prompts.

To connect your Laravel application to MS SQL server you may need to add following configuration to your config/database.php file to connections section:

'sqlsrv' => [
    'driver' => 'sqlsrv',
    'host' => env('DB_HOST', 'localhost'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'sa'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
],

After this application should be able to successfully connect to MS Sql server.

To import database, copy database *.BAK files to project folder, open sqlcmd console

sqlcmd -U sa -P 'Secret123'

and run following queries to import MYDB.BAK database backup file

RESTORE DATABASE [mydb] FROM DISK='/home/vagrant/project/MYDB.BAK'
WITH  FILE = 1,  
MOVE N'MYDB_dat' TO N'/var/opt/mssql/data/mydb.mdf',
MOVE N'MYDB_log' TO N'/var/opt/mssql/data/mydb.ldf',
NOUNLOAD,  REPLACE,  STATS = 1
GO

That’s basically all to install and run MS SQL on your Homestead Vagrant box, if you have any questions, feel free to contact!