Paginating data collections with zend-paginator

zend-paginator is a flexible
component for paginating collections of data and presenting that data to users.

Pagination is a standard UI solution
to manage the visualization of lists of items, like a list of posts in a blog
or a list of products in an online store.

zend-paginator is very popular among Zend Framework developers, and it’s often
used with zend-view, thanks to
the pagination control view helper zend-view provides.

It can be used also with other template engines. In this article, I will
demonstrate how to use it with Plates.

Usage of zend-paginator

The component can be installed via composer, using
the following command:

$ composer require zendframework/zend-paginator

To consume the paginator component, we need a collection of items.
zend-paginator ships with several different adapters for common collection
types:

  • ArrayAdapter, which works with PHP arrays;
  • Callback, which allows providing callbacks for obtaining counts of items and lists of items;
  • DbSelect, to work with a SQL collection (using zend-db);
  • DbTableGateway, to work with a Table Data Gateway (using the TableGateway
    feature from zend-db.
  • Iterator, to work with any Iterator instance.

If your collection does not fit one of these adapters, you can create a custom
adapter. To do so, you will need to implement
ZendPaginatorAdapterAdapterInterface, which defines two methods:

  • count() : int
  • getItems(int $offset, int $itemCountPerPage) : array

Each adapter need to return the total number of items in the collection,
implementing the count() method, and a portion (a page) of items starting
from $offset position with a size of $itemCountPerPage per page.

With these two methods we can use zend-paginator with any type of collection.

For instance, imagine we need to paginate a collection of blog posts and we
have a Posts class that manage all the posts. We can implement an adapter
like this:

require 'vendor/autoload.php';

use ZendPaginatorAdapterAdapterInterface;
use ZendPaginatorPaginator;
use ZendPaginatorScrollingStyleSliding;

class Posts implements AdapterInterface
{
    protected $posts = [];

    public function __construct()
    {
      // Read posts from file/database/whatever
    }

    public function count()
    {
        return count($this->posts);
    }

    public function getItems($offset, $itemCountPerPage)
    {
        return array_slice($this->posts, $offset, $itemCountPerPage);
    }
}

$posts = new Posts();
$paginator = new Paginator($posts);

Paginator::setDefaultScrollingStyle(new Sliding());
$paginator->setCurrentPageNumber(1);
$paginator->setDefaultItemCountPerPage(8);

foreach ($paginator as $post) {
  // Iterate on each post
}

$pages = $paginator->getPages();
var_dump($pages);

In this example, we created a zend-paginator adapter using a custom Posts
class. This class stores the collection of posts using a protected array
($posts). This adapter is then passed to an instance of Paginator.

When creating a Paginator, we need to configure its behavior.
The first setting is the scrolling style. In the example above, we used the
Sliding
style, a Yahoo!-like scrolling style that positions the current page number as
close as possible to the center of the page range.

Scrolling style

Note: the Sliding scrolling style is the default style used by zend-paginator. We need
to set it explicitly using Paginator::setDefaultScrollingStyle() only if we
do not use zend-servicemanager
as a plugin manager. Otherwise, the scrolling style is loaded by default from
the plugin manager.

The other two configuration values are the current page number and the number
of items per page. In the example above, we started from page 1, and we count 8
items per page.

We can then iterate on the $paginator object to retrieve the post of the
current page in the collection.

At the end, we can retrieve the information regarding the previous page, the
next page, the total items in the collection, and more. To get these values
we need to call the getPages() method. We will obtain an object like this:

object(stdClass)#81 (13) {
  ["pageCount"]=>
  int(3)
  ["itemCountPerPage"]=>
  int(8)
  ["first"]=>
  int(1)
  ["current"]=>
  int(1)
  ["last"]=>
  int(3)
  ["next"]=>
  int(2)
  ["pagesInRange"]=>
  array(3) {
    [1]=>
    int(1)
    [2]=>
    int(2)
    [3]=>
    int(3)
  }
  ["firstPageInRange"]=>
  int(1)
  ["lastPageInRange"]=>
  int(3)
  ["currentItemCount"]=>
  int(8)
  ["totalItemCount"]=>
  int(19)
  ["firstItemNumber"]=>
  int(1)
  ["lastItemNumber"]=>
  int(8)
}

Using this information, we can easily build an HTML footer to navigate across
the collection.

Note: using zend-view, we can consume the paginationControl
helper, which emits an HTML pagination bar.

In the next section, I’ll demonstrate using the Plates
template engine.

An example using Plates

Plates implements templates using native PHP; it is fast and easy to use,
without any additional meta language; it is just PHP.

In our example, we will create a Plates template to paginate a collection of
data using zend-paginator. We will use bootstrap as
the UI framework.

For purposes of this example, blog posts will be accessible via the following URL:

/blog[/page/{page:d+}]

where [/page/{page:d+}] represents the optional page number (using the regexp
d+ to validate only digits). If we open the /blog URL we will get the
first page of the collection. To return the second page we need to connect to
/blog/page/2, third page to /blog/page/3, and so on.

For instance, we can manage the page parameter using a PSR-7 middleware class
consuming the previous Posts adapter, that works as follow:

use PsrHttpMessageResponseInterface;
use PsrHttpMessageServerRequestInterface;
use LeaguePlatesEngine;
use ZendPaginatorPaginator;
use ZendPaginatorScrollingStyleSliding;
use Posts;

class PaginatorMiddleware
{
    /** @var Posts */
    protected $posts;

    /** @var Engine */
    protected $template;

    public function __construct(Posts $post, Engine $template = null)
    {
        $this->posts    = $post;
        $this->template = $template;
    }

    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response, callable $next = null
    ) {
        $paginator = new Paginator($this->posts);
        $page = $request->getAttribute('page', 1);

        Paginator::setDefaultScrollingStyle(new Sliding());
        $paginator->setCurrentPageNumber($page);
        $paginator->setDefaultItemCountPerPage(8);

        $pages = $paginator->getPages();
        $response->getBody()->write(
            $this->template->render('posts', [
                'paginator' => $paginator,
                'pages' => $pages,
            ])
        );
        return $response;
    }
}

We used a posts.php template, passing the paginator ($paginator) and
the pages ($pages) instances. That template could then look like the following:

<?php $this->layout('template', ['title' => 'Blog Posts']) ?>

<div class="container">
  <h1>Blog Posts</h1>

  <?php foreach ($paginator as $post): ?>
    <div class="row">
      <?php // prints the post title, date, author, ... ?>
    </div>
  <?php endforeach; ?>

  <?php $this->insert('page-navigation', ['pages' => $pages]) ?>
</div>

The page-navigation.php template contains the HTML code for the page
navigation control, with button like previous, next, and page numbers.

<nav aria-label="Page navigation">
  <ul class="pagination">
    <?php if (! isset($pages->previous)): ?>
      <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
    <?php else: ?>
      <li><a href="/blog/page/<?php echo $pages->previous ?>" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
    <?php endif; ?>

    <?php foreach ($pages->pagesInRange as $num): ?>
      <?php if ($num === $pages->current): ?>
        <li class="active"><a href="/blog/page/<?php echo $num ?>"><?php echo $num ?> <span class="sr-only">(current)</span></a></li>
      <?php else: ?>
        <li><a href="/blog/page/<?php echo $num ?>"><?php echo $num ?></a></li>
      <?php endif; ?>
    <?php endforeach; ?>

    <?php if (! isset($pages->next)): ?>
      <li class="disabled"><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
    <?php else: ?>
      <li><a href="/blog/page/<?php echo $pages->next ?>" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>
    <?php endif; ?>
  </ul>
</nav>

Summary

The zend-paginator component of Zend Framework is a powerful and easy to use
package that provides pagination of data. It can be used as standalone component
in many PHP projects using different frameworks and template engines. In this
article, I demonstrated how to use it in general purpose applications.
Moreover, I showed an example using Plates and Bootstrap, in a PSR-7 middleware
scenario.

Visit the zend-paginator documentation
to find out what else you might be able to do with this component!

Source: Zend feed

Implement a SOAP server with zend-soap

zend-soap provides a full-featured
SOAP implementation. SOAP is an XML-based
web protocol designed to allow describing messages, and, optionally,
operations to perform. It’s similar to XML-RPC,
but with a few key differences:

  • Arbitrary data structures may be described; you are not limited to the basic
    scalar, list, and struct types of XML-RPC. Messages are often serializations
    of specific object types on either or both the client and server. The
    SOAP message may include information on its own structure to allow the server
    or client to determine how to interpret the message.

  • Multiple operations may be described in a message as well, versus the one
    call, one operation structure of XML-RPC.

In other words, it’s an extensible protocol. This provides obvious benefits,
but also a disadvantage: creating and parsing SOAP messages can quickly become
quite complex!

To alleviate that complexity, Zend Framework provides the zend-soap component,
which includes a server implementation.

Why these articles on RPC services?

In the past couple weeks, we’ve covered JSON-RPC
and XML-RPC. One feedback we’ve
seen is: why bother — shouldn’t we be creating REST services instead?

We love REST; one of our projects is Apigility, which
allows you to simply and quickly build REST APIs. However, there are occasions
where RPC may be a better fit:

  • If your services are less resource oriented, and more function oriented
    (e.g., providing calculations).

  • If consumers of your services may need more uniformity in the service
    architecture in order to ensure they can quickly and easily consume the
    services, without needing to create unique tooling for each service exposed.
    While the goal of REST is to offer discovery, when every payload to send or
    receive is different, this can often lead to an explosion of code when
    consuming many services.

  • Some organizations and companies may standardize on certain web service
    protocols due to existing tooling, ability to train developers, etc.

While REST may be the preferred way to architect web services, these and
other reasons often dictate other approaches. As such, we provide these RPC
alternatives for PHP developers.

What benefits does it offer over the PHP extension?

PHP provides SOAP client and server capabilities already via its
SOAP extension; why do we offer a component?

By default, PHP’s SoapServer::handle() will:

  • Grab the POST body (php://input), unless an XML string is passed to it.
  • Emit the headers and SOAP XML response body to the output buffer.

Exceptions or PHP errors raised during processing may result in a SOAP fault
response, with no details, or can result in invalid/empty SOAP responses
returned to the client.

The primary benefit zend-soap provides, then, is error handling. You can
whitelist exception types, and, when encountered, fault responses containing the
exception details will be returned. PHP errors will be emitted as SOAP faults.

The next thing that zend-soap offers is WSDL generation. WSDL allows you to
describe the web services you offer, so that clients know how to work with
your services. ext/soap provides no functionality around creating WSDL; it
simply expects that you will have a valid one for use with the client or server.

zend-soap provides an AutoDiscover class that uses reflection on the classes
and functions you pass it in order to build a valid WSDL for you; you can then
provide this to your server and your clients.

Creating a server

There are two parts to providing a SOAP server:

  • Providing the server itself, which will handle requests.
  • Providing the WSDL.

Building each follows the same process; you simply emit them with different HTTP
Content-Type headers, and under different HTTP methods (the server will always
react to POST requests, while WSDL should be available via GET).

First, let’s define a function for populating a server instance with classes
and functions:

use AcmeModel;

function populateServer($server, array $env)
{
    // Expose a class and its methods:
    $server->setClass(ModelCalculator::class);

    // Expose an object instance and its methods:
    $server->setObject(new ModelEnv($env));

    // Expose a function:
    $server->addFunction('AcmeModelping');
}

Note that $server is not type-hinted; that will become more obvious soon.

Now, let’s assume that the above function is available to us, and use it to
create our WSDL:

// File /soap/wsdl.php

use ZendSoapAutoDiscover;

if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
    // Only handle GET requests
    header('HTTP/1.1 400 Client Error');
    exit;
}

$wsdl = new AutoDiscover();
populateServer($wsdl, $_ENV);
$wsdl->handle();

Done! The above will emit the WSDL for either the client or server to consume.

Now, let’s create the server. The server requires a few things:

  • The public, HTTP-accessible location of the WSDL.
  • SoapServer options, including the actor URI for the server and SOAP
    version targeted.

Additionally, we’ll need to notify the server of its capabilities, via the
populateServer() function.

// File /soap/server.php

use ZendSoapServer;

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    // Only handle POST requests
    header('HTTP/1.1 400 Client Error');
    exit;
}

$server = new Server(dirname($_SERVER['REQUEST_URI']) . '/wsdl.php', [
    'actor' => $_SERVER['REQUEST_URI'],
]);

populateServer($server, $_ENV);
$server->handle();

The reason for the lack of type-hint should now be clear; both the Server and
AutoDiscover classes have the same API for populating the instances with
classes, objects, and functions; having a common function for doing so allows us
to ensure the WSDL and server do not go out of sync.

From here, you can point your clients at /soap/server.php on your domain, and
they will have all the information they need to work with your service.

Using zend-soap within a zend-mvc application

The above details an approach using vanilla PHP; what about using zend-soap
within a zend-mvc context?

To do this, we’ll need to learn a few more things.

First, you can provide Server::handle() with the request to process. This
must be one of the following:

  • a DOMDocument
  • a DOMNode
  • a SimpleXMLElement
  • an object implementing __toString(), where that method returns an XML string
  • an XML string

We can grab this information from the MVC request instance’s body content.

Second, we will need the server to return the response, so we can use it to
populate the MVC response instance. We can do that by calling
Server::setReturnResponse(true). When we do, Server::handle() will return an
XML string representing the SOAP response message.

Let’s put it all together:

namespace AcmeController;

use AcmeModel;
use ZendSoapAutoDiscover as WsdlAutoDiscover;
use ZendSoapServer as SoapServer;
use ZendMvcControllerAbstractActionController;

class SoapController extends AbstractActionController
{
    private $env;

    public function __construct(ModelEnv $env)
    {
        $this->env = $env;
    }

    public function wsdlAction()
    {
        /** @var ZendHttpRequest $request */
        $request = $this->getRequest();

        if (! $request->isGet()) {
            return $this->prepareClientErrorResponse('GET');
        }

        $wsdl = new WsdlAutoDiscover();
        $this->populateServer($wsdl);

        /** @var ZendHttpResponse $response */
        $response = $this->getResponse();

        $response->getHeaders()->addHeaderLine('Content-Type', 'application/wsdl+xml');
        $response->setContent($wsdl->toXml());
        return $response;
    }

    public function serverAction()
    {
        /** @var ZendHttpRequest $request */
        $request = $this->getRequest();

        if (! $request->isPost()) {
            return $this->prepareClientErrorResponse('POST');
        }

        // Create the server
        $server = new SoapServer(
            $this->url()
                ->fromRoute('soap/wsdl', [], ['force_canonical' => true]),
            [
                'actor' => $this->url()
                    ->fromRoute('soap/server', [], ['force_canonical' => true]),
            ]
        );
        $server->setReturnResponse(true);
        $this->populateServer($server);

        $soapResponse = $server->handle($request->getContent());

        /** @var ZendHttpResponse $response */
        $response = $this->getResponse();

        // Set the headers and content
        $response->getHeaders()->addHeaderLine('Content-Type', 'application/soap+xml');
        $response->setContent($soapResponse);
        return $response;
    }

    private function prepareClientErrorResponse($allowed)
    {
        /** @var ZendHttpResponse $response */
        $response = $this->getResponse();
        $response->setStatusCode(405);
        $response->getHeaders()->addHeaderLine('Allow', $allowed);
        return $response;
    }

    private function populateServer($server)
    {
        // Expose a class and its methods:
        $server->setClass(ModelCalculator::class);
    
        // Expose an object instance and its methods:
        $server->setObject($this->env);
    
        // Expose a function:
        $server->addFunction('AcmeModelping');
    }
}

The above assumes you’ve created routes soap/server and soap/wsdl, and uses
those to generate the URIs for the server and WSDL, respectively; the
soap/server route should map to the SoapController::serverAction() method
and the soap/wsdl route should map to the SoapController::wsdlAction()
method.

Inject your dependencies!

You’ll note that the above example accepts the AcmeModelEnv instance via
its constructor, allowing us to inject a fully-configured instance into the
server and/or WSDL autodiscovery. This means that you will need to provide a
factory for your controller, to ensure that it is injected with a fully
configured instance — and that likely also means a factory for the
model, too.

To simplify this, you may want to check out the ConfigAbstractFactory
or ReflectionBasedAbstractFactory,
both of which were introduced in version 3.2.0 of zend-servicemanager.

Using zend-soap within PSR-7 middleware

Using zend-soap in PSR-7 middleware is essentially the same as what we detail
for zend-mvc: you’ll need to pull the request content for the server, and use
the SOAP response returned to populate a PSR-7 response instance.

The example below assumes the following:

  • You are using the UrlHelper and ServerUrlHelper from zend-expressive-helpers
    to generate URIs.
  • You are routing to each middleware such that:
    • The ‘soap.server’ route will map to the SoapServerMiddleware, and only
      allow POST requests.
    • The ‘soap.wsdl’ route will map to the WsdlMiddleware, and only
      allow GET requests.
namespace AcmeMiddleware;

use AcmeModel;
use PsrHttpMessageResponseInterface;
use PsrHttpMessageServerRequestInterface;
use ZendDiactorosResponseTextResponse;
use ZendSoapAutoDiscover as WsdlAutoDiscover;
use ZendSoapServer as SoapServer;

trait Common
{
    private $env;

    private $urlHelper;

    private $serverUrlHelper;

    public function __construct(
        ModelEnv $env,
        UrlHelper $urlHelper,
        ServerUrlHelper $serverUrlHelper
    ) {
        $this->env = $env;
        $this->urlHelper = $urlHelper;
        $this->serverUrlHelper = $serverUrlHelper;
    }

    private function populateServer($server)
    {
        // Expose a class and its methods:
        $server->setClass(ModelCalculator::class);
    
        // Expose an object instance and its methods:
        $server->setObject($this->env);
    
        // Expose a function:
        $server->addFunction('AcmeModelping');
    }
}

class SoapServerMiddleware
{
    use Common;

    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        callable $next
    ) {
        $server = new SoapServer($this->generateUri('soap.wsdl'), [
            'actor' => $this->generateUri('soap.server')
        ]);
        $server->setReturnResponse(true);
        $this->populateServer($server);

        $xml = $server->handle((string) $request->getBody());

        return new TextResponse($xml, 200, [
            'Content-Type' => 'application/soap+xml',
        ]);
    }

    private function generateUri($route)
    {
        return ($this->serverUrlHelper)(
            ($this->urlHelper)($route)
        );
    }
}

class WsdlMiddleware
{
    use Common;

    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        callable $next
    ) {
        $server = new WsdlAutoDiscover();
        $this->populateServer($server);

        return new TextResponse($server->toXml(), 200, [
            'Content-Type' => 'application/wsdl+xml',
        ]);
    }
}

Since each middleware has the same basic construction, I’ve created a trait with
the common functionality, and composed it into each middleware. As you will
note, the actual work of each middleware is relatively simple; create a server,
and marshal a resposne to return.

In the above example, I use the zend-diactoros-specific
TextResponse type to generate the response; this could be any other response
type, as long as the Content-Type header is set correctly, and the status code
is set to 200.

Per the note above, you will need to
configure your dependency injection container to inject the middleware instances
with the model and helpers.

Summary

While SOAP is often maligned in PHP circles, it is still in wide use within
enterprises, and used in many cases to provide cross-platform web services with
predictable behaviors. It can be quite complex, but zend-soap helps smooth out
the bulk of the complexity. You can use it standalone, within a Zend Framework
MVC application, or within any application framework you might be using.

Visit the zend-soap documentation
to find out what else you might be able to do with this component!

Source: Zend feed

Custom Input Components

You’ll surely come across instances in your own projects, where you’d like to wrap a form input within a custom component. This way, you can have a single place to attach all custom sanitization, validation, and behavior. However, in the process, you’ll also find that the useful v-model directive no longer works the way it usually does.

In this episode, we’ll learn exactly what Vue’s v-model does, and then review how to make it work on any custom component. View the demo for this lesson on GitHub.
Source: Laracasts

Laravel Auth Redirection

When you use Laravel’s built-in Auth system, it provides a redirectTo property on the LoginController, RegisterController, and ResetPasswordController. This property allows you to define the location you want your users sent to after they complete the action.

Inside of Laravel this is setup and implemented through a RedirectsUsers trait and a minor improvement has been added to this that will now allow you to define a redirectTo method with a fallback to the property.

public function redirectPath()
{
    if (method_exists($this, 'redirectTo')) {
        return $this->redirectTo();
    }

    return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}

With this new method, you now have easier access to perform other actions or to set the location dynamically. As an example, let’s pretend when a user logs in you want to redirect them to their public account page. Inside your LoginController you can now do something like this:

public function redirectTo()
{
    return '/@'.auth()->user()->username;
}

Source: Laravel News

Seven Tips to Learn Laravel More Effectively

As the community grows, there are many resources available to help you learn Laravel. That’s great! But, how do you choose the best one? Which will be the best use of your time to read or watch? For those new to the framework, I’m sure these questions are on your mind, here are seven tips to help you learn Laravel more effectively.

Some of these tips will be specific to Laravel, while others are more general for learning any programming language or framework. Let’s get started.

1. Don’t Start With the Official Documentation. Seriously.

The first thing newcomers typically look at is the official Laravel documentation. Don’t get me wrong—the docs are great! But, there’s an expectation you already have some knowledge of the PHP ecosystem and modern tooling.

As an example, the first section of the documentation is installation, it’s not just “Download and install.” You need to know how to use Composer; how to use the terminal or command line, how to run commands, how web servers work etc. Which leads me to the second tip…

2. Learn PHP, OOP, Terminal, and Composer First.

It might sound funny, but I see more and more people trying to learn Laravel without learning PHP first. Another similar trend is those who try to use jQuery without learning any JavaScript. Stop fooling yourselves and start with fundamentals.

To begin learning any modern PHP framework (Laravel, Symfony, or others), you need to be good at PHP. And, especially, object-oriented programming; all frameworks are written in OOP mode and you need to be fluent in classes, objects, properties, methods, dependencies, traits, and other “keywords.”

In general, I would advise you to create at least one simple project with plain PHP without any framework. You will then have a better understanding of PHP which will allow you to use the Laravel internal functions more efficiently.

Also, Composer,  a tool that, in my opinion, made PHP great again. Knowledge of Composer will help you competently use Laravel dependencies, which is a crucial part of modern PHP development.

Oh, and did I mention terminal? Or command line for Windows OS. Again, modern PHP frameworks use commands for a lot of their functionality—generating code, installing libraries, changing settings, running deployments, etc. You have to know the basics.

All of this is how much you need to know BEFORE starting with Laravel. It doesn’t look as easy anymore, does it? But let’s move on; we’re just getting started with tips.

3. Books, Courses, or Videos? Free or Premium?

This is probably the most important question: what is the best way to learn? It’s a personal choice; some people are better readers, while others prefer videos. And that’s fine! Ask yourself, what is more convenient for you?

The information you want to consume should be properly structured. You cannot just take random articles or videos from YouTube—it won’t give you the desired result. You need the author to explain the information in a consistent flow, step-by-step. Otherwise, you may lose your train of thought and not be able to understand further lessons.

That is, by the way, the fundamental difference between free and premium lessons online. Some  say you can learn to program just from searching the internet because there’s a huge amount of information available for free. Which is partly true, but if you choose that path, you will have to spend a lot of time trying to piece it all together. Paid courses or books are often the best because the information is prepared for you in a convenient way, so you don’t waste your time searching.

Here are three resources that I recommend to start with:

4. Stop Reading, Start Writing

It is impossible to learn any programming without writing code. Don’t spend too much time reading books or watching videos; start coding as early as you can. In fact, after finishing every lesson or section, immediately try it in practice.

In general, I would advise you to try creating a test project during the course of learning. It makes the process not only more realistic, but more motivating. Without a proper goal and outcome in mind, it’s emotionally hard to continue learning the theory.

And, if you only write code, you will bump into hurdles and will have questions to ask. By having problems and overcoming them, you evolve as a developer and increase your knowledge.

5. Learn to Use Google and StackOverflow.

While not directly related to Laravel, it is important. It astonishes me how many forum topics are created by people who could Google the answer in two minutes.

Can you properly use Google? Example: search for “Laravel,” excluding the word “beginners” but include only results from the Laracasts website? The query should look like this:

laravel -beginners site:laracasts.com

That’s how deep you should go to find relevant information.

StackOverflow should be used similarly. Their results usually appear among the first Google entries. Do you understand how to choose the right answer to the question? It’s not always the first one. Can you tell which Laravel version it’s for? Is it still relevant information?

It’s not only about reading the forums; you should be able to ask questions in a correct way and style. Usually, every forum and community has its own culture, rules, and behavior expectations. If you are polite, patient, and respectful, you have better chances of receiving help.

6. Find a Mentor.

The biggest problem with learning programming is troubleshooting when something doesn’t work. The best solution to this problem is asking someone else for help.

I’ve been a mentor for a few students and was told without my help they wouldn’t be able to solve problems and potentially would have even given up learning. That’s how powerful personal, external help is!

Where should you look for a mentor? In your community, whether it’s local or online. Twitter has a great community of developers, so if you find someone there who seems like they can help—don’t be shy and get in contact. Mention them on Twitter, follow for a while, find their email, and start the conversation.

7. Don’t. Give. Up.

As mentioned in the previous tip, when hitting a problem you can’t solve, it’s easy to give up on learning. Maybe that’s the very reason why so many start learning, but only a few actually become professional developers. It’s not all rainbows and butterflies; the path will be full of problems, difficult questions, disbelief, and desire to throw the computer out of the window. I’ve been there, trust me. The main thing is to continue, no matter what. Be creative; there’s always a way out.

Finally, speaking of continuous progress, my last advice is to not take long breaks between your learning sessions. Constantly learn something new—every week or even every day. It’s similar to working out; if you miss one day, it’s harder to get back into the rhythm.

So these are my tips—I hope you will find your best way to learn and potentially we’ll create awesome Laravel projects together!

Source: Laravel News

Bear: Beautiful Note Taking App for iPhone, iPad and Mac

I am a fiddly writer. I store all of my written prose as text files in Dropbox. Not only are my writings saved for many future generations, but I am not locked into any particular writing ecosystem. I can switch between various writing apps (which happens often) with ease. Hopefully, these small details on how I personally approach an app like Bear is useful to you when you need to decide if it’s worth believing me. Now, onward.

You can’t move your mouse in the Mac App Store without hitting a distraction-free writing app. I originally thought that’s what I was getting with Bear. I was wrong.

When you first click on it’s playfully subtle red and white icon, you see a simple app that looks incredible. When you first tap out a short note in Bear is when you realize this app isn’t just well designed, It’s handcrafted software everyone can use.

Bear is simple but surprisingly deep. For instance, Bear has it’s own writing syntax that is similar but not exactly the same as John Gruber’s Markdown. I found this peculiar at first but after poking around in the settings I found that Bear contains an option that will force it to abide by the Markdown syntax instead.

Bear contains just enough features to get a fiddly writer like myself ready to go. One of my favorite features is the ability to link to other notes within the app with ease. This makes it possible to do all sorts of things, from stringing together a series of notes about various projects all the way up to writing a book.

There’s also a simple but surprisingly extendable tags systems that makes it easy to organize all kinds of writings. You can put all of your written words into Bear without the fear of losing them.

The most impressive thing about Bear isn’t even a feature at all. It’s the pricing structure. It’s free to download on Mac and iOS. You can get syncing if you subscribe to Bear Pro which is $1.49 per month or $14.99 per year. This is one of the most affordable subscriptions I’ve seen for an application of this caliber. I am very impressed the developers have launched Bear in this way.

If you like fussy coffee, quality leather shoes, or a handmade desk, then you’ll like Bear. It’s handcrafted software that anyone can use.

Source: Laravel News

Laravel Scheduler Adds Support for Running Hourly Tasks on a Certain Minute

The Laravel Scheduler now includes a new method hourlyAt that will allow you to define the minute within the hour that it should run. This helpful in situations where you have a task that should run hourly but not at the top of the hour.

Using the same simple syntax as all the other methods and here is a quick example:

$schedule->command('mytask')->hourlyAt(15);

This will set the command to run every hour on the 15th minute. Of course, you can still pair it with the other methods to get more fine-grained control:

$schedule->command('mytask')
    ->weekdays()
    ->hourlyAt(15);

This feature is included starting at v5.3.29 and will allow you to use the familiar syntax instead of having to jump into using the cron method to define it.

Source: Laravel News

Shared State 101

Let’s begin reviewing shared state. You’ll absolutely run into this before too long. If you have multiple Vue instances or components that need access to the same data – and they also need to be in sync with one another – how exactly do we allow for that?
Source: Laracasts

Finding Suitable Work: What Hiring Managers Are Looking For

A large component to finding suitable work is being a proficient interviewer. One of the things many devs lean on when landing a better paying job is their ability to do well during the technical interview. They put so much emphasis on the code and think it’ll be all they need to secure that next opportunity. However, nailing the technical interview is only the first component of finding suitable work as a developer. To be qualified for most higher-level positions in tech, you need to be well-rounded.

What do I mean by that? Working for a company is more than just coding. Whether you’re helping build something from the ground up; maintaining an established product; or stepping away from code to focus on strategy, hiring managers need to know you can truly handle all of the aspects of the job. They need to see you are capable of communicating effectively and working well with your coworkers. Beyond that, they need to be fairly certain you aren’t going to make their lives harder.

Here’s what we know about managers. First, they need to be good motivators; great managers know how to engage their employees to get the most out of them. To this end, they need to build solid relationships with each of their team members while also holding those individuals accountable. In short, a manager’s job is twofold: to complete their technical tasks and ensure their team members are completing theirs as well. That’s why when managers are looking to fill out their staffs, they want people who know the value of putting the team over the individual.

We are living in a world which is increasingly more connected. The internet and ever-advancing technology has given companies the chance to truly sell anywhere. Huge, well-funded companies have always had access to the world beyond their city or state. But now, local mom-and-pop shops can put their products on sites like Etsy and go global. They can do it in the time it takes to fill out a profile and upload a few pictures. What this means is most of the work we do, we cannot do alone. We need to be collaborators.

And that’s why great managers are looking for people that value making their team successful. They know team success trumps individual success every time. Take the example above of the small local company going global via Etsy. Etsy is created and maintained by a team, just like the small artisan selling their wares online. Even if they are solopreneurs, they had help along the way from people that believed in them. Those people helped by asking questions about what was needed and how they could assist.

Do you see the pattern? Teams of people can achieve more than individuals can by themselves. No one becomes successful alone; and for that reason, we are truly all collaborators. And to be good collaborators, we need to be good communicators.

When looking to add a few more people, great managers value strong communication skills. I can’t tell you how many times I’ve heard this sentence: “They were a great developer, but I couldn’t hire them because there’s no way they I could put them in front of a client.” It’s no longer enough just to be smart; being innovative and having good ideas are great traits. However, if you can’t communicate those ideas, all of those wonderful qualities are worthless. There is indeed a time and a place for hacking away in a corner; situational solitude can result in a significant push when necessary. A lot of the time, though, you’re going to have to talk to people.

This is the reason communication matters even more than talent. Conflicts will arise. Differences in opinion can escalate to full-blown arguments. Brainstorming sessions need to take place. Presentations occasionally happen. Having a good command of code will only get you so far; you need to be a solid communicator. When you have command of that, collaboration will become a lot easier.

I’ve talked about a lot of big picture concepts and examples, so let’s relate this back to getting hired on a great team. Good collaborators propel projects forward. They do this by knowing their strengths and how those strengths relate to their place on their team. You can show this in an interview by highlighting your ability to work well with others. Maybe you played an integral and specific role on a big project recently; tell them how you articulated your role to your team and what you accomplished.

Good communicators speak eloquently to their team members and managers, and they tackle problems head on through empathetic communication. Showcase this in your next interview by describing a time you were involved in a conflict at work and how you handled it successfully.

Bottom line, hiring managers are looking for people that play well with others, communicate effectively, and can do the technical aspects of their job well.

Source: Laravel News

Laravel Powered Blogging App Canvas Launches V3

Canvas, the minimal blogging app built on Laravel has just launched V3, and it includes many new features including moving the core code out into a new Easel package. Here are some highlights of the other new features.

New Installation Wizard

When you create your first Canvas site, you are greeted with a friendly welcome message with instructions on starting the installation through the Artisan command, php artisan canvas:install

After going through the six steps, your new blog is ready to go.

New Media Manager

New in v3 is a media manager that is built on Vue.js and allows you to upload images and put them in separate folders. This can be accessed through the editor toolbar or from the sidebar.

Split Pane Markdown Editing

Canvas supports writing your blog posts in Markdown and uses the SimpleMDE editor that includes a toolbar for common commands, as well as a split pane preview so you can preview in real time.

Even More, New Features

Also in V3, Canvas now includes an update wizard, syntax highlighting, a light and dark theme, and role-based user management.

If you are looking to start a blog this year, Canvas would be a good choice.

Source: Laravel News

1 2