Page 22 of 23

Laravel 4: How To Use Jquery UI Sortable

Laravel 4: How To Use Jquery UI Sortable

Click and drag sorting

I needed a way to change the sort order of my data inside of an admin interface which I have created. After a little looking around, I found many tutorials which would show how to get this done with JQuery. But wouldn’t show the best way to handle this data (and in my case using Laravel to handle this data). I dug around for quite a bit, but I ended up finding this lovely little tutorial by dragonfire1119 which was called How To Use Jquery UI Sortable In Laravel 4.

The only trouble is, when you follow this tutorial, it could be tidied up a little, here is my version…

// Place this inside your View

@foreach($categories as $category)
    sort me
@endforeach

Here is the JQuery…

$(document).ready(function () {
    $('.sortable').sortable({ cursor: 'move', axis: 'y', update: function () {
        var order = $(this).sortable('toArray');
        $.post('{{ URL::route('Sliders::sort') }}', { order: order })
    }
    });
});

And then your Controller will look like this…

<?php
public function sort() {
    $input = Input::get('order');
    $i = 1;
    
    foreach($input as $value) {
        $banner = Banner::find($value);
    
        $banner->sort_by = $i;
        $banner->save();
        
        $i++;
    }
}

The JQuery and Controller could also look like this…

$(document).ready(function () {
    $('.sortable').sortable({ cursor: 'move', action (event, ui) {
        var data = $(this).sortable('serialize');
        
        $.ajax({ data: data, type: 'POST', url: '{{ URL::route('Sliders::sort') }}' });
    }
    });
});

Updated Controller…

<?php
public function sort() {
    $input = Input::get('item');
    $i = 0;
    foreach($input as $value) { $banner = Banner::find($value);
        $banner->sort_by = $i;
        $banner->save();
        $i++;
    }
}

I think that both work just as well and it is down to personal preference. If you would like to know where I got the second method from, you can take a look here.

As always, if you have any comments/suggestion the please feel free to let me know in the comments.

Laravel AJAX Tutorial Using HTML5’s FormData

Laravel AJAX Tutorial Using HTML5’s FormData

For this tutorial, I will show you guys how I managed to create an image uploader for your profile image. This is very similar to how Facebook’s/Twitter’s functionality.

Routes

First of all, let’s create the routes, for this, we will need to create a get and post route…

<?php
Route::get('{username}', 'UsernameController@show');
Route::post('{username}/upload', 'UploadController@profileImage');

Controllers

Remember that you can name the controllers and methods anything you like, as long as you keep everything consistent. Now we need to create the controllers and methods which are as follows…

<?php
// User Controller, index mehod
public function show($username) {
    $user = User::where('username', $username)->first(); $userData = User::find($user->id)->UserDetail;

    return View::make('user', array( 'userData'=> $userData ))->with('user', $user);
}

We are trying to get the user’s information where it matches in the URI. As you can see, I have a one to one relationship with a user and a user’s information (called UserDetail). I believe the user array could be placed along with the user data array. However, I decided to place this inside the with a method.

Now we need to handle the image data which will upload the image to the background. Without anyone knowing it’s happening…

<?php
// UploadController, profileImage method
public function profileImage($username){
    $user = User::where('username', $username)->first();

    $temp = $_FILES['upload']['tmp_name']; $image = $_FILES['upload']['name'];
    $ext = pathinfo($image, PATHINFO_EXTENSION);
    
    $newFilename = uniqid($user->id);
    
    if(!is_dir("images/$username/")) { mkdir("images/$username", 0777); }
    
    $img = Image::make($temp);
    
    $img->fit(130, 130);
    
    $src = "images/$username/$newFilename.$ext";
    
    $img->save($src);
    
    $query = User::find($user->id)->profileImage; $query->src = $src;
    $query->alt = $username . '\'s Profile Image';
    $query->save();
}

Firstly, we need to match the username with the username in the URI, after this, we grab the image and process it. Please note that I am using the Intervention/Image package, which you can easily grab and install to implement it on your website. We check to see if the directory exists, if it doesn’t, then we create it with r/w permissions. I then use the image package to create an image which is 130px X 130px, the fit method will automatically crop the image so it doesn’t look stretched and horrible. We then give it a source which tells it where to save this image which then gets saved. Afterwards, we call the database and find the user to set the image src and alt rows.

Blade templates

Now that we have all the backend magic happening, we actually need to create a view which displays the form and automatically refreshes the image upon upload completion…

@extends('layout')

@section('content')

    <div class="row">
    
        <div id="profile-wrapper">
        
            <div class="large-2 columns pull-left">
                <img class="profile-thumb th" src="/{{ $user->profileImage->src }}"
                    alt="Profile Image" />
            </div>
            
            <h2>About</h2>
            
            @if(isset($loggedIn) && $loggedIn->username == $user->username)
                <a href="#" class="upload-link"> Upload a file </a>
                <div class="hidden-upload">
                    {{ Form::open(array(
                        'action' => array('User::upload',
                        $user->username),
                        'files' => 'true',
                        'id' => 'image-form')) }}
                        {{ Form::file('upload', array('class' => 'profile-upload')) }}
                    {{ Form::close() }}
                </div>
            @endif
        </div>
    
        {{ $userData->about }}
    </div>

@stop

Javascript (Ajax)

We only want to show this hidden form if the user is logged in and it’s the same logged in user which is seeing their own profile. As you can see, we are using Laravel’s blade syntax which makes this page look a lot cleaner and easier to see what is going on. Right, now we need the JQuery which will send the image to the post controller we recently created…

<script>
    if(isset(user)) {
        form.change(function() {
            var formData = new FormData($('form')[0]);
            
            jQuery.ajax({
                url: '{{ $user->username }}/upload'
                data: formData,
                processData: false,
                contentType: false,
                type: 'post',
                success: function(
                    window.location.reload(true);
                )
            })
        })
    }
</script>

I have created my own scripts.blade.php which gets placed into my layout.blade.PHP, you can do the same, or you can include this within the page itself. I then added an if statement to avoid any errors for when a user isn’t logged in. For our JQuery creates a new format function and passes in the form we created, we then call the ajax method and pass it some parameters.

  • URL: sets the URL to where the image needs to get passed to, this is the route we created above.
  • data: sets the data to formData.
  • processData and contentType are both set to false, this has to be set to avoid any future errors.
  • type: We set this to post as it is a post method.
  • success: On success, it will refresh the window to display the newly uploaded image.

Styles

There you guys have it, this is all we need to create our really awesome AJAX upload form. However, you guys might be wondering, how do we hide the form? We here are the optional steps so you can create a hidden form which gets shown upon mouse hover…

.upload-link {
    position: absolute;
    top: 100px;
    left: 35px;
    z-index: 0;
}

#profile-wrapper:hover .upload-link {
    display: inline; background: rgba(0, 0, 0, 0.8);
    color: #fff;
    padding: 2px;
}

.hidden-upload {
    position: absolute;
    top: 100px;
    left: 35px;
    z-index: 1;
}

.hidden-upload .profile-upload {
    opacity: 0;
}

Now, that is all there is (I promise). If you have any questions, comments or feedback, then please feel free to drop a comment down below. I always like to read what you guys have to say and love replying back to you. I hope you look forward to my next Blog post.

Laravel user Registration and Login

Using Laravel packages to help us

This will be a fairly simple tutorial as I’m not re-creating the wheel here. I started by developing a login/registration system by myself until I start talking to people in Laravel’s IRC. There is a package which did everything I needed it to do which was as follows…

  • Register a user with the following credentials; Username, Email, Password and of course Confirm Password.
  • The user then gets sent an email to confirm registration.
  • The user confirms registration and can now use the website by logging in.
  • The link in case the user forgets the password, which then creates a link to confirm so the user can then change his/her password.
  • Remember me functionality.
  • Logging out
  • Completely customisable in terms of layout and functionality.

Some people had spoken about a Laravel package which does all of this called Zicaco/confide. This package is absolutely brilliant and does everything I could ask for whilst still maintaining the simplicity of migrating it into something you have already developed.

We need to start off by installing this package, place “zizaco/confide”: “~4.0@dev” into your Composer’s require key. You then place ZizacoConfideServiceProvider’, inside Laravel’s provider’s array. Finally, add this into Laravel’s aliases array ‘Confide’ => ‘ZizacoConfideFacade’, .

(PLEASE NOTE: I am currently using version 3.2.* of this package and I currently haven’t upgraded. I am sure that the experience will be similar, but if you have any queries then feel free to email me).

Once you have installed your package successfully, you can run these commands to get everything up and running… php artisan confide:controllerphp artisan confide:routescomposer dump-autoload. And as the docs say, you are good to go.

You can test it out by going to localhost/users/create to see what it has made for you. Of course, you can go on and change the layout, the control and anything else which you find you need to change.

If you need any help, then please let me know and I will try to help you out. I will also be trying to upgrade to the latest version and will release a step by step guide on how to do this.

Thoughts on my social networking site and what has changed

Carrying on with my social networking website

I’ve had a lot to think about when it comes to the where I want to take my website. Firstly, do I really want to take on such a big task of trying to beat Facebook on my own, when they have a huge team? The answer to that is no, no I don’t. I have always had some great ideas with what I wanted to do. However, the fact is, I couldn’t carry this out on my own.

What could I do instead? I figured I should go for something which possibly hasn’t been done before. It could be similar to something which has already been done, that way I can keep my ideas on the straight and narrow. There have been so many instances where I would come up with these ideas and they would just explode, I would get so excited about these new prospects. However, because most of my thoughts have rarely been carried out before, I would get frustrated because I couldn’t find the help I needed.

Expanding the social idea

What if I created a website which could help like-minded people? With projects too big for them to carry out themselves? It then came to me, like a brick smacking into my face. I would create a website where users could explain a project they want to create, and then find people close by with similar ideas. They could then meet up somewhere and express these ideas, then they could create the project into something real.

My website will be about users coming in to make a project. You then find people who are interested and meet up with them to make this project a reality. As it’s initially a project, my website won’t be asking you about wages or some sort of payment, it will be up to you to make that part a reality.

I would like to apologise for the lack of posts lately. Things have been a bit hectic for me and my family. Please bear with me. I can assure you, I will still be posting. I will be making my website a reality for people to enjoy.

Virgin Media Calling and Asking for Password

Receiving a phone call from Virgin Media

Last week sometime, I received a phone call from Virgin Media. The caller said he would like to talk to me regarding my account, which at first seemed fairly legit. I asked him what the problem was and to his response, I was shocked.

The reply was “Firstly Michael, I need to know your password”. After telling him that I’m not giving him my password as he rang me. He should know that he is talking to the correct person.

Personally, I felt like this could have easily been some fraudulent call. After him not giving up on this, despite me asking several times what it was actually regarding and him repeating… “I can’t tell you until you give me your password”. I said to him that you can send me a letter with what this is regarding and I hung up.

The problem continues

This wouldn’t have been a problem if I was the one who rung them up. But the fact he did this when calling ME, I was not going to tell him. I personally feel that this isn’t the best way to handle the call, and he should have asked me other questions like my address or say the 2nd and 5th characters of my password. If I were to have friends/family around, I wouldn’t tell him my password as it could be used on other websites like Facebook and Twitter, so it should be dealt in another way.

The terms even speak about not asking for your password (shown below). Surely this means they are going against their own terms on this.

If anyone has had the same, or similar experiences on this then please share your thoughts and what you did to deal with the situation.

They did in fact send me a letter, and it was to do with being behind on payments. Why they couldn’t even hint at this still baffles me, but I rang them up and had it all sorted.

Protecting your information

Any information sent to us is protected using robust security methods. The methods we use are industry-standard ensuring data is safeguarded whilst being sent over unprotected communications paths such as the internet. When it reaches us, we store it securely and only provide access to it by those authorised. Although we safeguard your personal information once received, Virgin Media cannot guarantee the safety of any personal information you transmit to us using online methods.

We will never ask you for your Virgin Media identification, authentication passwords or PIN numbers directly associated with your Virgin Media account in any unsolicited phone calls or unsolicited emails. In accordance with our Terms and Conditions, you are responsible for keeping your password and PIN secure and we very strongly recommend you do not disclose them to anyone (unless you wish to authorise them to access your account and potentially incur charges on your account).

https://store.virginmedia.com/the-legal-stuff/privacy-policy.html

Nice little Laravel tip (Blade Ternary Operator)

Just today, I was looking at using a ternary operator in Laravel’s Blade templating system and thought to myself… “There must be a better way of doing this”. After a quick Google aanndd… BEHOLD THE OR STATEMENT! Since version 4.1 they managed to sneak in this “or” statement and it’s managed to bypass so many people (I figured this out by the lack of voices shouting about this on Google).

So, instead of doing something like this…

{{ (isset($title)) ? $title : 'default title here' }}

You can try using “or” like so…

{{ $title or 'default title here' }}

And there you have it ladies and gentlemen, your future Blade documents will look even more lovely. Please, thank me later. 😊

Laravel Localhost removing /public/index.php

I have been in the Laravel chats for quite a while now and one question which I see regularly is how to remove the public/index.php directory on Localhost. The easiest way to do this (and the way I always use) is to open up your Command prompt or Terminal and cd into the main directory of your project then run php artisan serve. That’s it. You’re done. Don’t believe me? Check out https://localhost:8000 and admire your Laravel work.

Another way, but a bit more complicated would be to set up a virtual host (vhost) and point it to the public folder inside your projects main directory. Have a Google around if this is what you prefer and you will find so many tutorials showing you just how to do this.

Something which is a lot newer is Vagrant, now this will set up a Virtual Machine which you can SSH into and run a local environment for your PHP. Check it out and find some tutorials on installing a LAMP environment inside your Vagrantproject.

Laravel’s version 4.2 will be coming packaged with something called Homestead which will have a Vagrant configuration. This will allow you to go straight into Laravel and run a Vagrant box straight away with little to no configuration what so ever.

So, try each of these examples out and find out which one is easiest for you. If you have another way then please let us know in the comments and share your experiences with setting up a Laravel project.

Laravel Dynamic Navigation Package

I have managed to create a dynamic navigation package for Laravel which can be seen in my previous post. If you go to Packagist you will be able to find my package under checkeredmichael/navigation.

I have created a readme with this package which should get you started on implementing it within your own projects. I would like to get as many people as possible to use this package and come back with feedback/bug fixes.

This is my very first public package and I will be using it to expand on other packages such as my very own admin package for Laravel which will be created in the future.

If anyone requires further assistance then please let me know in the comments of this post or contact me.

Laravel Dynamic Menu Tutorial (Best for Admin packages)

Learn more Laravel

Creating a dynamic menu

Thanks to this very Laravel topic over at Laravel.io and Josh Benham. I managed to find out how to make my very own dynamic menu. In this tutorial, I will show you exactly how it’s done. Hopefully, you will now be able to make amazing admin packages for Laravel.

For those that just want the package then you can download it the Laravel dynamic navigation package. Otherwise, continue below.

First off, I am doing this in my very own package. My directory structure will look pretty much like anyone else file structure which will be within the src/Package/Admin. Hopefully, you should be able to follow this along just fine. However, if you have any problems or even any suggestions for improvements then feel free to let me know.

Within my Admin folder, I create a new folder called services and create a file called ‘Menu.php’. This is the code you should type within this file…

services/Menu.php

<?php

namespace PackageAdminServices;

use Illuminate\Support\Facades\HTML;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\URL;

class Menu { 
    protected $items;
    protected $current;
    protected $currentKey;
    
    public function __construct() {
        $this->current = Request::url();
    }

    /** Shortcut method for create a menu with a callback.
     * This will allow you to do things like fire an even on creation.
     * @param callable $callback Callback to use after the menu creation 
     * @return object
     */ 
    public static function create($callback) {
        $menu = new Menu(); $callback($menu);
        $menu->sortItems(); return $menu;
    }
    
    /** Add a menu item to the item stack
     * @param string $key Dot separated hierarchy 
     * @param string $name Text for the anchor 
     * @param string $url URL for the anchor 
     * @param integer $sort Sorting index for the items 
     * @param string $icon URL to use for the icon 
     */
    public function add($key, $name, $url, $sort = 0, $icon = null) { 
        $item = array(
            'key' => $key,
            'name' => $name,
            'url' => $url,
            'sort' => $sort,
            'icon' => $icon,
            'children' => array()
            );
        $children = str_replace('.', '.children.', $key);
        array_set($this->items, $children, $item);
        if ($url == $this->current) {
            $this->currentKey = $key; }
    }
    
    /** Recursive function to loop through items and create a menu 
     * @param array $items List of items that need to be rendered 
     * @param boolean $level Which level you are currently rendering 
     * @return string
     */
    public function render($items = null, $level = 1) { 
        $items = $items ?: $this->items;
        $attr = array( 'class' => 1 === $level ? 'menu level-1' : 'level-' . $level );
        $menu = '<ul' . HTML::attributes($attr) . '>'; foreach($items as $item) {
            $classes = array('menu__item');
            $classes[] = $this->getActive($item);
            $has_children = sizeof($item['children']);
            
            if ($has_children) {
                $classes[] = 'parent';
            }
            $menu .= '<li' . HTML::attributes(array('class' => implode(' ', $classes))) . '>';
            $menu .= $this->createAnchor($item);
            $menu .= ($has_children) ? $this->render($item['children'], ++$level) : '';
            $menu .= '</li>'; }
            $menu .= '</ul>';
        return $menu;
    }
    
    /** Method to render an anchor 
     * @param array $item Item that needs to be turned into a link 
     * @return string 
     */
    private function createAnchor($item) {
        $output = '<a class="menu__item" href="' . $item['url'] . '">';
        $output .= $this->createIcon($item);
        $output .= $item['name'];
        $output .= '</a>';
        return $output;
    }
    
    /** Method to render an icon 
     * @param array $item Item that needs to be turned into a icon
     * @return string
     */
    private function createIcon($item) {
        $output = ''; if($item['icon']) {
            $output .= sprintf('<i class="glyphicon glyphicon-%s"></i>', $item['icon']);
        } return $output;
    }
    
    /** Method to sort through the menu items and put them in order 
     * @return void 
     */
    private function sortItems() { 
        usort($this->items, function($a, $b) {
            if($a['sort'] == $b['sort']) {
                return 0;
            }
            return ($a['sort'] < $b['sort'] ? -1 : 1);
        });
    }
    
    /** Method to find the active links 
     * @param array $item Item that needs to be checked if active 
     * @return string 
     */
    private function getActive($item) {
        $url = trim($item['url'], '/');
        if ($this->current === $url) {
            return 'active current';
        }
        
        if(strpos($this->currentKey, $item['key']) === 0) {
            return 'active';
        }
        
        return '';
    }
}

Get all that?

This code will set you up for all the behind-the-scenes stuff. Hopefully, most of it is pretty self-explanatory (like most of Laravel). The code should be well commented to give you a grasp on what is going on.

Next, we will make our navigation which will be within the views folder. I created an inc folder within my views to keep things tidy called ‘navigation.blade.php’. And my code goes a little like this…

<?php use PackageAdminServicesMenu; ?>

{{ Menu::create(function($menu) {
    Event::fire('admin.menu.build', $menu); })
    ->render(); }}

This will display your navigation, but the only trouble is that we haven’t actually built it. Here we have the code to build our dynamic navigation menu. Inside your AdminServiceProvider.php you need to add this line into your public function boot()

include __DIR__ . '/../../events.php';

This will tell your package where to find the events page which will build up your navigation. Your events.php needs to be in the same place as your routes and filters. This should be in the src folder…

<?php
Event::listen('admin.menu.build', function($menu){
    $menu->add('index', 'Index', URL::route('Admin::index.index'), 1, 'dashboard');
    $menu->add('users', 'Users', URL::route('Admin::users.index'), 100, 'users'); });

Here we use the event listen method used in Laravel to build our menu. The first part of our add method gives a key which enables a check to see if it’s the current page or not. The second part adds text to your link, URL::route will be the route name which you use in your routes.php. We then have these numbers which says where they should be displayed on the nav and users or dashboard is a font awesome icon.

Phew, that was a lot to take in…

Hopefully, this is enough to get anyone started on a dynamic nav, if you need to use it on more packages then just add the code to the service provider, add another event .php and then create similar code to that above which will build up your navigation even more.

I would also like to thank Josh Benham for his help and support. Check out the discussion at laravel.io.

If you would like to pull in the package I created then take a look at my next post. Laravel dynamic navigation package.

Feel free to add your own feedback in the comments below

Subscribe to my weekly newsletter!

If you’d like a weekly email in your inbox, please join the newsletter by entering your email address below.

Subscription received!

Please check your email to confirm your newsletter subscription.

By subscribing, you agree with Revue’s Terms and Privacy Policy.

Composer Private Repository Problems

Cross development can be a pain…

Recently I have been finding out the slight differences between Windows and Linux for use with Laravel and Composer. One difference is Windows isn’t picky about the way you set out Composer’s packages which can be a major problem. Here’s the issue I had and what I had to do to get it going…

{
    "name"
}: 
"laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"repositories": [
    {
        "type": "vcs",
        "url": "git@bitbucket.org:mbrookspulse8/admin.git",
        "url": "git@bitbucket.org:pulse8/haulfryn-admin-sliders.git",
        "url": "git@bitbucket.org:pulse8/haulfryn-admin-parks.git",
        "branches-path": false,
        "tags-path": false
    }
],
"require": {
    "laravel/framework": "4.1.*",
    "cartalyst/sentry": "2.1.*",
    "imagine/Imagine": "0.5.0",
    "edvinaskrucas/notification": "2.*",
    "way/generators": "dev-master",
    "pulse8/admin": "dev-master",
    "pulse8/sliders": "dev-master",
    "pulse8/parks": "dev-master",
    "geedmo/yamm3": "dev-master"
},
"autoload": {
    "classmap":
    [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php"
    ]
},
"scripts": {
    "post-install-cmd"
}:
[ "php artisan clear-compiled", "php artisan optimize" ],
"post-update-cmd": [ "php artisan clear-compiled", "php artisan optimize" ],
"post-create-project-cmd": [ key:generate" ] },
"config": {
    "preferred-install": "dist"
},
"minimum-stability": "stable"
}

As you can see, I placed all of my private VPS URLs into one JSON object. On Windows, everything was fine and dandy, nothing was overwritten and everything could be found easily. However, when I placed it all on the server, this is where I ran into problems. Linux is more strict on standards (which is definitely not a bad thing) and caused a lot of aches and pains for me as I wasn’t coding to these standards. It took me and my team a whole day to suss out what was wrong, but this was our finished code for the private VPS URLs…

"repositories": 
[
    { 
        "type": "vcs",
        "url": "git@bitbucket.org:mbrookspulse8/admin.git",
        "branches-path": false,
        "tags-path": false
    },
    {
        "type": "vcs",
        "url": "git@bitbucket.org:pulse8/haulfryn-admin-sliders.git",
        "branches-path": false,
        "tags-path": false
    },
    {
        "type": "vcs",
        "url": "git@bitbucket.org:pulse8/haulfryn-admin-parks.git",
        "branches-path": false, "tags-path": false
    }
],

They have been separated into their own object and now runs perfectly fine on Windows and Linux. Had similar issues? If so then please feel free to share and let me know how you overcame them.