Blog and News

Phalcon 3.0.1 released

We are excited to announce the immediate availability of Phalcon 3.0.1 [LTS].

This maintenance release fixes bugs and improve the stability of Phalcon:

  • Fixed memory leaks in PHP7 when setting undeclared properties in models
  • Fixed Phalcon\Cache\Backend\Redis::flush in order to flush cache correctly
  • Fixed Phalcon\Mvc\Model\Manager::getRelationRecords to correct using multi relation column #12035
  • Fixed Phalcon\Acl\Resource. Now it implements Phalcon\Acl\ResourceInterface #11959
  • Fixed save method for all cache backends. Now it updates the _lastKey property correctly #12050
  • Fixed virtual foreign key check when having multiple keys #12071
  • Phalcon\Config\Adapter\Ini constructor can now specify parse_ini_file() scanner mode #12079
  • Fixed Phalcon\Cache\Backend\Apc::save due to which the Apc::increment/Apc::decrement could not be used properly #12109
  • Fixed Phalcon\Mvc\Model\Criteria::inWhere so that now the second parameter can be an empty array #10676
  • Fixed ORM related memory leak #12115, #11995, #12116
  • Fixed incorrect Phalcon\Mvc\View::getActiveRenderPath behavior #12139
  • Fixed Phalcon\Security\Random::base64Safe so that now the method returns correct safe string #12141
  • Fixed the Phalcon\Translate\Adapter\Gettext::getOptionsDefault visibility #12157
  • Enabled PHQL cache for PHP7 to improve performance and reuse plannings

Update/Upgrade

Phalcon 3.0.1 can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

We encourage existing Phalcon 3 users to update to this maintenance version.

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 3.0.0 final (LTS) released

The Phalcon team is very excited to share some news with our community!

The last few months, we have been working hard to push 2.1 out, which contains significant enhancements as well as some API changes that require attention so as not to break compatibility with your application.
On top of that we have been working in making Zephir PHP7 compatible so that you can enjoy Phalcon in your PHP7 application. Some news first though:

Versioning

For any future Phalcon releases we are adopting SemVer (http://semver.org). In short:

Given a version number MAJOR.MINOR.PATCH, increment the:
* MAJOR version when you make incompatible API changes,
* MINOR version when you add functionality in a backwards-compatible manner, and
* PATCH version when you make backwards-compatible bug fixes.
* Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

Since 2.1 has many API changes, we decided that it would be best to not release it as is and start using SemVer to better communicate with the community and keep track of our releases.

2.1 is dead, all hail 3.0

As mentioned above, 2.1 will not be fully backwards compatible. As a result, we are changing the version number to 3.0.

PHP version support

The Phalcon team takes security very seriously and thus have decided to provide support to PHP versions that are supported. As of 3.0, PHP 5.3 and 5.4 will be deprecated. We are making a small exception to this rule and will continue to support 5.5 for a little while, but since its support has expired a few days ago, it will too be deprecated in a future release.

The goodie bag

So what does 3.0 offer? The changelog is extensive as you can see. Below are highlights of the changes as well as areas you need to concentrate.

• PHP 5.3 and 5.4 are fully deprecated.
You can compile the code on your own, but we will not be able to support it nor can we guarantee that it will work as you expect it to. PHP 5.3 support expired mid 2014 and 5.4 expired mid 2015. We need to ensure our applications have all known vulnerabilities on the PHP side fixed and patched, thus we will not support any unsupported PHP version. This excludes PHP 5.5, whose support expired a few days ago. We will deprecate 5.5 in a future release but will make sure that you all know beforehand so that you can prepare.

INCOMPATIBLE: You will need to upgrade your PHP installation to 5.6. You can always continue to use the Phalcon version you are using, but in 3.0 support for PHP 5.4 has been deprecated and we cannot guarantee that PHP 5.5 will be fully functional.

APPLICATION

Phalcon\Cli\Console and Phalcon\Mvc\Application now inherits Phalcon\Application.
This change makes the interfaces more uniformed and offers additional functionality to the respective applications (cli/mvc)

BEANSTALK

• Added \Phalcon\Queue\Beanstalk::ignore().
Removes the named tube from the watch list for the current connection.

• Added \Phalcon\Queue\Beanstalk::pauseTube().
Can delay any new job being reserved for a given time.

• Added \Phalcon\Queue\Beanstalk::kick().
It moves jobs into the ready queue. If there are any buried jobs, it will only kick buried jobs. Otherwise it will kick delayed jobs.

// Kick the job, it should move to the ready queue again
if (false !== $job->kick()) {
    $job = $this->client->peekReady();
}

• Added \Phalcon\Queue\Beanstalk::listTubeUsed().
Returns the tube currently being used by the client.

• Added \Phalcon\Queue\Beanstalk::listTubesWatched().
Returns a list tubes currently being watched by the client.

• Added \Phalcon\Queue\Beanstalk::peekDelayed().
Return the delayed job with the shortest delay left.

$this->client->put('testPutInTube', ['delay' => 2]);
$job = $this->client->peekDelayed();

• Added \Phalcon\Queue\Beanstalk::jobPeek().
Returns the next available job.

$this->client->choose(self::TUBE_NAME_1);
$jobId = $this->client->put('testPutInTube');
$job   = $this->client->jobPeek($jobId);
$this->assertEquals($jobId, $job->getId());

CACHE

• The cache backend adapters now return boolean when calling Phalcon\Cache\BackendInterface::save

// Returns true/false
$result = $backendCache->save('my_key', $content);

• Added Phalcon\Cache\Frontend\Msgpack. MsgPack is a new frontend cache. It is an efficient binary serialization format, which allows exchanging data among multiple languages like JSON.

use Phalcon\Cache\Backend\File;
use Phalcon\Cache\Frontend\Msgpack;

// Cache the files for 2 days using Msgpack frontend
$frontCache = new Msgpack(
    [
        'lifetime' => 172800,
    ]
);

// Create the component that will cache 'Msgpack' to a 'File' backend
// Set the cache file directory - important to keep the '/' at the end of
// of the value for the folder
$cache = new File(
    $frontCache, 
    [
        'cacheDir' => '../app/cache/',
    ]
);

// Try to get cached records
$cacheKey = 'robots_order_id.cache';
$robots   = $cache->get($cacheKey);

if ($robots === null) {
    // $robots is null due to cache expiration or data do not exist
    // Make the database call and populate the variable
    $robots = Robots::find(['order' => 'id']);

    // Store it in the cache
    $cache->save($cacheKey, $robots);
}

// Use $robots
foreach ($robots as $robot) {
    echo $robot->name, "\n";
}

• Fixed bug of destroy method of Phalcon\Session\Adapter\Libmemcached

• Added Phalcon\Cache\Backend\Memcache::addServers to enable pool of servers for memcache

$memcache->addServers('10.4.6.10', 11000, true);
$memcache->addServers('10.4.6.11', 11000, true);
$memcache->addServers('10.4.6.12', 11000, true);

CRYPT

• Mcrypt is replaced with openssl in Phalcon\Crypt #11530#11486
Due to the lack of updates for mcrypt for a number of years, its slow performance and the fact that the PHP core team decided to deprecate mcrypt as soon as possible (version 7.1 onward), we have replaced it with the much faster and supported openssl.

• Default encrypt algorithm in Phalcon\Crypt is now changed to AES-256-CFB

• Removed methods setMode(), getMode(), getAvailableModes() in Phalcon\CryptInterface (no longer apply with openssl)

BACKWARDS INCOMPATIBLE: Backwards compatibility from openssl to mcrypt is problematic if not impossible. We had to remove several methods that are no longer applicable. Additionally the rijndael-256 from mcrypt is no longer valid in openssl. The default encryption algorithm is AES-256-CFB

If you have data that has already been encrypted with mcrypt, you will need first to decrypt it before upgrading to 3.0 and then encrypt it again using 3.0 and therefore openssl. Failure to do so will result in loss of data. A port is available in the incubator. Please see the code here

DATABASE

• Dropped support of Oracle #12008#12009
Support of Oracle has been dropped from the Phalcon Core for the following reasons:
•• The lack of Oracle maintainer
•• The lack of relevant experience among the Phalcon Core Team
•• Weak support or interest from the community
•• Incomplete implementation that creates only the illusion of support for Oracle
•• Some issues hampering for the support of PHP 7 in Phalcon

Oracle components will be ported to the Phalcon Incubator. If the adapter receives support and enhancements from the community, we will consider making it part of the core again.

DI

Phalcon\Di is now bound to services closures allowing use Phalcon\Di as $this to access services within them. Additionally, closures used as handlers inMvc\Micro are now bound to the $app instance

Old way:

$diContainer->setShared(
    'modelsCache',
    function () use ($config) {
        $frontend = '\Phalcon\Cache\Frontend\\' . $config->get('modelsCache')->frontend;
        $frontend = new $frontend(
            [
                'lifetime' => $config->get('modelsCache')->lifetime,
            ]
        );
        $config   = $config->get('modelsCache')->toArray();
        $backend  = '\Phalcon\Cache\Backend\\' . $config['backend'];

        return new $backend($frontend, $config);
    }
);

New way:

$diContainer->setShared(
    'modelsCache',
    function () {
        $frontend = '\Phalcon\Cache\Frontend\\' . $this->config->get('modelsCache')->frontend;
        $frontend = new $frontend(
            [
                'lifetime' => $this->config->get('modelsCache')->lifetime,
            ]
        );
        $config   = $this->config->get('modelsCache')->toArray();
        $backend  = '\Phalcon\Cache\Backend\\' . $config['backend'];

        return new $backend($frontend, $config);
    }
);

Also note the nested DI behavior:

$foo = function() {
    get_class($this); // DI
    $bar = function () {
        get_class($this); // DI
        $baz = function () {
            // etc
        }
    }
}

• If an object is returned after firing the event beforeServiceResolve in Phalcon\Di it overrides the default service localization process

DISPATCHER

• Added Phalcon\Dispatcher::hasParam().

public function testAction() 
{    
    if (true === $this->dispatcher->hasParam('foo')) {
        // Parameter exists
    }
}

• Added method getActionSuffix() in Phalcon\DispatcherInterface. This allows you change the 'Action' suffix in controller actions.

• Corrected behavior to fire the dispatch:beforeException event when there is any exception during dispatching #11458

• CLI parameters are now handled consistently.

• Added Phalcon\Mvc\Controller\BindModelInterface and associated model type hint loading through dispatcher.

• Added Phalcon\Mvc\Collection::update, Phalcon\Mvc\Collection::create and Phalcon\Mvc\Collection::createIfNotExist

public function createAction() 
{
    /**
     * Creates a document based on the values in the attributes, if not found by criteria
     */
    $robot = new Robot();
    $robot->name = 'MyRobot';
    $robot->type = 'Droid';
    $robot->create();
}

public function createOverrideAction() 
{
    /**
     * Create a document
     */
    $robot = new Robot();
    $robot->name = 'MyRobot';
    $robot->type = 'Droid';
    //create only if robot with same name and type does not exist
    $robot->createIfNotExist( array( 'name', 'type' ) );
}

public function updateAction() 
{
    /**
     * Update a document
     */
    $robot = Robots::findFirst(['id' => 1]);
    $robot->name = 'MyRobot';
    $robot->type = 'Droid';
    $robot->update();
}

EVENTS

• Now Phalcon\Events\Event implements Phalcon\Events\EventInterface

Phalcon\Events\Event::getCancelable renamed to Phalcon\Events\Event::isCancelable

BACKWARDS INCOMPATIBLE: Any references to getCancelable will stop working. You will need to rename the function to isCancelable

Old way:

public function cancelAction()
{
    if (true === $this->eventsManager->getCancelable()) {
        // do something here
    }
}

New way:

public function cancelAction()
{
    if (true === $this->eventsManager->isCancelable()) {
        // do something here
    }
}

• Removed Phalcon\Events\Manager::dettachAll in favor of Phalcon\Events\Manager::detachAll

BACKWARDS INCOMPATIBLE: Any references to dettachAll will stop working. You will need to rename the function to detachAll

Old way:

public function destroyAction()
{
    $this->eventsManager->dettachAll()
}

New way:

public function destroyAction()
{
    $this->eventsManager->detachAll()
}

FLASH

• Added ability to autoescape Flash messages #11448

$flash = new Phalcon\Flash\Session;
$flash->setEscaperService(new Phalcon\Escaper);

$flash->success("<script>alert('This will execute as JavaScript!')</script>");
echo $flash->output();
// <div class="successMessage"><script>alert('This will execute as JavaScript!')</script></div>

• Fixed Phalcon\Session\Flash::getMessages.
Now it returns an empty array in case of non existent message type request #11941

Old result:

use Phalcon\Session\Flash as FlashSession;

$flash = new FlashSession();
$flash->error('Error Message');
var_dump($flash->getMessages('success', false));

array (size=1)
  'error' => 
    array (size=1)
      0 => string 'Error Message' (length=13)

New result:

use Phalcon\Session\Flash as FlashSession;

$flash = new FlashSession();
$flash->error('Error Message');
var_dump($flash->getMessages('success', false));

array (size=0)
  empty

HTTP REQUEST/RESPONSE

• Added default header: Content-Type: "application/json; charset=UTF-8" in method Phalcon\Http\Response::setJsonContent

Old way:

use Phalcon\Http\Response;

$data     = 'Phlying with Phalcon';
$response = new Response();
$response->setContentType('application/json;');
$response->setJsonContent($data)
$response->send();

New way:

$data     = 'Phlying with Phalcon';
$response = new Response();
$response->setJsonContent($data)
$response->send();

• Added ability to spoof the HTTP request method.
Most browsers do not support sending PUT and DELETE requests via the method attribute in an HTML form. If the X-HTTP-Method-Override header is set, and if the method is a POST, then it is used to determine the 'real' intended HTTP method. The _method request parameter can also be used to determine the HTTP method, but only if setHttpMethodParameterOverride(true) has been called. By including a _method parameter in the query string or parameters of an HTTP request, Phalcon will use this as the method when matching routes. Forms automatically include a hidden field for this parameter if their submission method is not GET or POST.

• Added support of CONNECT, TRACE and PURGE HTTP methods.
- CONNECT: A variation of HTTP tunneling when the originating request is behind a HTTP proxy server. With this mechanism, the client first requests the HTTP proxy server to forward the TCP connection to the final endpoint. The HTTP proxy server then establishes the connection on behalf of the client.
- TRACE: A method used for debugging which echoes input back to the user. Note that this method is dangerous, since it introduces a risk whereby an attacker could steal information such as cookies and possibly server credentials.
- PURGE: Although not defined in the HTTP RFCs, some HTTP servers and caching systems implement this method and use it to purge cached data.

• Refactored Phalcon\Http\Request::getHttpHost.
Now it always returns the hostname or empty an string. Optionally validates and cleans host name #2573#11921

• Renamed Phalcon\Http\Request::isSoapRequest to Phalcon\Http\Request::isSoap and Phalcon\Http\Request::isSecureRequest to Phalcon\Http\Request::isSecure.
Left the originals functions as aliases and marked them deprecated.

CAUTION: Any references to isSoapRequest need to be renamed to isSoap. Any references to isSecureRequest need to be renamed to isSecure.

Old way:

public function testAction()
{
    if (true === $this->request->isSoapRequest()) {
        //
    }

    if (true === $this->request->isSecureRequest()) {
        //
    }
}

New way:

public function testAction()
{
    if (true === $this->request->isSoap()) {
        //
    }

    if (true === $this->request->isSecure()) {
        //
    }
}

• Added Phalcon\Http\Request::setStrictHostCheck and Phalcon\Http\Request::isStrictHostCheck to manage strict validation of the host name.

use Phalcon\Http\Request;

$request = new Request;

$_SERVER['HTTP_HOST'] = 'example.com';
$request->getHttpHost(); // example.com

$_SERVER['HTTP_HOST'] = 'example.com:8080';
$request->getHttpHost(); // example.com:8080

$request->setStrictHostCheck(true);
$_SERVER['HTTP_HOST'] = 'ex=am~ple.com';
$request->getHttpHost(); // UnexpectedValueException

$_SERVER['HTTP_HOST'] = 'ExAmPlE.com';
$request->getHttpHost(); // example.com

• Added Phalcon\Http\Request::getPort.
Returns the port on which the request is made i.e. 80, 8080, 443 etc.

• Added setLastModified method to Phalcon\Http\Response
Sets the Last-Modified header

public function headerAction()
{
    $this->response->setLastModified(new DateTime());
}

• Add setContentLength method to Phalcon\Http\Response
Sets the response content-length

public function headerAction()
{
    $this->response->setContentLength(2048);
}

LOADER

• Removed support for prefixes strategy in Phalcon\Loader

BACKWARDS INCOMPATIBLE: In Phalcon 2, you could load classes using a specific prefix. This method was very popular before namespaces were introduced. For instance:

<?php

use Phalcon\Loader;

// Creates the autoloader
$loader = new Loader();

// Register some prefixes
$loader->registerPrefixes(
    array(
        "Example_Base"    => "vendor/example/base/",
        "Example_Adapter" => "vendor/example/adapter/",
        "Example_"        => "vendor/example/"
    )
);

// Register autoloader
$loader->register();

// The required class will automatically include the
// file vendor/example/adapter/Some.php
$some = new Example_Adapter_Some();

This functionality is no longer supported

• Added \Phalcon\Loader::registerFiles and \Phalcon\Loader::getFiles. registerFiles registers files that are "non-classes" hence need a "require". This is very useful for including files that only have functions. getFiles
returns the files currently registered in the autoloader

$loader->registerFiles(
    [
        'fuctions.php',
        'arrayFunctions.php',
    ]
);

MODELS

• Changed constructor of Phalcon\Mvc\Model to allow pass an array of initialization data

$customer = new Customer(
    [
        'Name'   => 'Peter',
        'Status' => 'active',
    ]
);
$customer->save();

Phalcon\Mvc\Model now implements JsonSerializable making easy serialize model instances

$customers = Customers::find();
echo json_encode($customers); // {['id':1,...],['id':2,...], ...}

Phalcon\Mvc\Model\Criteria::getOrder renamed to Phalcon\Mvc\Model\Criteria::getOrderBy

BACKWARDS INCOMPATIBLE: Any references to getOrder will stop working. You will need to rename the function to getOrderBy

• Added method getOption() in Phalcon\Mvc\Model\RelationInterface
Returns an option by the specified name. If the option does not exist null is returned

• Added OR operator for Phalcon\Mvc\Model\Query\Builder methods: betweenWhere, notBetweenWhere, inWhere and notInWhere

$builder->betweenWhere('price', 100.25, 200.50);     // Appends a BETWEEN condition
$builder->notBetweenWhere('price', 100.25, 200.50);  // Appends a NOT BETWEEN condition
$builder->inWhere('id', [1, 2, 3]);                  // Appends an IN condition
$builder->notInWhere('id', [1, 2, 3]);               // Appends an NOT IN condition

• Added new getter Phalcon\Mvc\Model\Query\Builder::getJoins()
Returns the join parts from query builder

• When destructing a Mvc\Model\Manager PHQL cache is cleaned

• Added FULLTEXT index type to Phalcon\Db\Adapter\Pdo\Mysql

• Fixed afterFetch event not being sent to behaviors

• Fixed issue with Model::__set that was bypassing setters #11286

• Fixed issue with Model::__set setting hidden attributes directly when setters are not declared #11286

Phalcon\Mvc\Model\Manager::load() now can load models from aliased namespaces

Phalcon\Mvc\Model\Transaction\Manager now correctly keeps account of transactions #11554

Phalcon\Db\Dialect\Sqlite now maps additional column types to SQLite columns equivalents.

• Fixed Phalcon\Mvc\Model\Resultset::update() - Removed endless loop queries

• Fixed Phalcon\Mvc\Model\Manager::_mergeFindParameters - Merging conditions fix

ROLES

• Added Phalcon\Acl\RoleAware and Phalcon\Acl\ResourceAware Interfaces. Now you can pass objects to Phalcon\Acl\AdapterInterface::isAllowed as roleName and resourceName, also they will be automatically passed to function defined in Phalcon\Acl\AdapterInterface::allow or Phalcon\Acl\AdapterInterface::deny by type

use UserRole;       // Class implementing RoleAware interface
use ModelResource;  // Class implementing ResourceAware interface

// Set access level for role into resources
$acl->allow('Guests', 'Customers', 'search');
$acl->allow('Guests', 'Customers', 'create');
$acl->deny('Guests', 'Customers', 'update');

// Create our objects providing roleName and resourceName
$customer     = new ModelResource(1, 'Customers', 2);
$designer     = new UserRole(1, 'Designers');
$guest        = new UserRole(2, 'Guests');
$anotherGuest = new UserRole(3, 'Guests');

// Check whether our user objects have access to the operation on model object
$acl->isAllowed($designer, $customer, 'search')     // Returns false
$acl->isAllowed($guest, $customer, 'search')        // Returns true
$acl->isAllowed($anotherGuest, $customer, 'search') // Returns true

Phalcon\Acl\AdapterInterface::allow and Phalcon\Acl\AdapterInterface::deny have 4th argument - function. It will be called when using Phalcon\Acl\AdapterInterface::isAllowed

Phalcon\Acl\AdapterInterface::isAllowed have 4th argument - parameters. You can pass arguments for a function defined in Phalcon\Acl\AdapterInterface:allow or Phalcon\Acl\AdapterInterface::deny as associative array where key is argument name

// Set access level for role into resources with custom function
$acl->allow(
    'Guests', 
    'Customers', 
    'search',
    function ($a) {
        return $a % 2 == 0;
    }
);

// Check whether role has access to the operation with custom function
$acl->isAllowed('Guests', 'Customers', 'search', ['a' => 4]); // Returns true
$acl->isAllowed('Guests', 'Customers', 'search', ['a' => 3]); // Returns false

• Fixed wildcard inheritance in Phalcon\Acl\Adapter\Memory #12004#12006

use Phalcon\Acl;
use Phalcon\Acl\Adapter\Memory as MemoryAcl;

$acl = new MemoryAcl();

$acl->setDefaultAction(Acl::DENY);

$roleGuest      = new Role("guest");
$roleUser       = new Role("user");
$roleAdmin      = new Role("admin");
$roleSuperAdmin = new Role("superadmin");

$acl->addRole($roleGuest);
$acl->addRole($roleUser, $roleGuest);
$acl->addRole($roleAdmin, $roleUser);
$acl->addRole($roleSuperAdmin, $roleAdmin);

$acl->addResource("payment", ["paypal", "facebook",]);

$acl->allow($roleGuest->getName(), "payment", "paypal");
$acl->allow($roleGuest->getName(), "payment", "facebook");

$acl->allow($roleUser->getName(), "payment", "*");

echo $acl->isAllowed($roleUser->getName(), "payment", "notSet");  // true
echo $acl->isAllowed($roleUser->getName(), "payment", "*");       // true
echo $acl->isAllowed($roleAdmin->getName(), "payment", "notSet"); // true
echo $acl->isAllowed($roleAdmin->getName(), "payment", "*");      // true

ROUTES

• Routes now can have an associated callback that can override the default dispatcher + view behavior

• Amended Phalcon\Mvc\RouterInterface and Phalcon\Mvc\Router. Added missed addPurge, addTrace and addConnect methods.
Added addConnect for the CONNECT HTTP method, addPurge for the PURGE HTTP method and addTrace for the TRACE HTTP method

• Placeholders :controller and :action in Mvc\Router now defaults to /([\\w0-9\_\-]+) instead of /([\\a-zA-Z0-9\_\-]+)

• Modifier #u (PCRE_UTF8) is now default in regex based routes in Mvc\Router

Mvc\Router\Route now escapes characters such as . or + to avoid unexpected behaviors

• Fixed the use of the annotation router with namespaced controllers

• Fixed matching host name by Phalcon\Mvc\Route::handle when using port on current host name #2573

SECURITY

• Added Phalcon\Security::hasLibreSsl and Phalcon\Security::getSslVersionNumber
Mostly these are used internally but can be used to get information about libreSsl.

• Changed default hash algorithm in Phalcon\Security to CRYPT_BLOWFISH_Y

Phalcon\Security is using now Phalcon\Security\Random

• Enforced that Phalcon\Security::getToken() and Phalcon\Security::getTokenKey() return a random value per request not per call

Phalcon\Security::getToken() and Phalcon\Security::getTokenKey() are using now Phalcon\Security::_numberBytes instead of passed as argument or hard coded value

Phalcon\Security::hash() corrected not working CRYPTSTDDES, CRYPTEXTDES, MD5, CRYPT_SHA256

Phalcon\Security::hash() CRYPT_SHA512 fixed wrong salt length

• Added missing unit-tests for Phalcon\Security

SESSION

• Removed Phalcon\Session #11340

BACKWARDS INCOMPATIBLE: Any references to Phalcon\Session have to be removed and replaced with the relevant adapter class

• Fixed the Session write callback #11733

TEXT

• Added ability to use custom delimiter for Phalcon\Text::camelize and Phalcon\Text::uncamelize #10396

use Phalcon\Text;

public function displayAction()
{
    echo Text::camelize('c+a+m+e+l+i+z+e', '+'); // CAMELIZE
}

• Fixed Phalcon\Text:dynamic() to allow custom separator #11215

VIEW

• An absolute path can now be used to Mvc\View::setLayoutsDir
You can now use one layout path for all the landing pages of your application for instance, even from separate projects

• Now Phalcon\Mvc\View supports many views directories at the same time

• Return false from an action disables the view component (same as $this->view->disable())

public function displayAction()
{
    // Do some stuff here

    return false; // Same as $this->view->disable();
}

• Return a string from an action takes it as the body of the response

• Return a string from an Mvc\Micro handler takes it as the body of the response

public function displayAction()
{
    // Do some stuff here

    // $this->response->setContent('<h1>Hello World</h1>');
    return '<h1>Hello World</h1>';
}

• Fixed odd view behavior #1933 related to setLayout() and pick()

VALIDATION

Phalcon\Mvc\Model\Validation is now deprecated in favor of Phalcon\Validation
The functionality of both components is merged into one, allowing us to reduce the codebase while offering the same functionality as before.

Old way:

namespace Invo\Models;

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Validator\Email as EmailValidator;
use Phalcon\Mvc\Model\Validator\Uniqueness as UniquenessValidator;

class Users extends Model
{
    public function validation()
    {
        $this->validate(
            new EmailValidator(
                [
                    'field' => 'email',
                ]
            )
        );

        $this->validate(
            new UniquenessValidator(
                [
                    'field'   => 'username',
                    'message' => 'Sorry, That username is already taken',
                ]
            )
        );

        if ($this->validationHasFailed() == true) {
            return false;
        }
    }
}

New way:

namespace Invo\Models;

use Phalcon\Mvc\Model;
use Phalcon\Validation;
use Phalcon\Validation\Validator\Email as EmailValidator;
use Phalcon\Validation\Validator\Uniqueness as UniquenessValidator;

class Users extends Model
{
    public function validation()
    {
        $validator = new Validation();

        $validator->add(
            'email', //your field name
            new EmailValidator([
                'model' => $this,
                'message' => 'Please enter a correct email address'
            ])
        );

        $validator->add(
            'username',
            new UniquenessValidator([
                'model' => $this,
                'message' => 'Sorry, That username is already taken',
            ])
        );

        return $this->validate($validator);
    }
}

• Method isSetOption in Phalcon\Validation\ValidatorInterface marked as deprecated, please use hasOption

CAUTION: Any references to isSetOption need to be renamed to hasOption

Old way:

if (true === $validation->isSetOption('my-option')) {
    //
}

New way:

if (true === $validation->hasOption('my-option')) {
    //
}

• Added internal check allowEmpty before calling a validator. If it option is true and the value of empty, the validator is skipped

• Added option to validate multiple fields with one validator (fix uniqueness validator as well), also removes unnecessary model => $this in Phalcon\Validation\Validator\Uniqueness.

Phalcon\Validation\Validator\Alpha now correctly validates non-ASCII characters #11386

• Added Phalcon\Validation\CombinedFieldsValidator, validation will pass array of fields to this validator if needed

Phalcon\Validation\Validator\Digit now correctly validates digits #11374

use Phalcon\Validation\Validator\Digit as DigitValidator;

$validator->add(
    'height', 
    new DigitValidator(
        [
            'message' => ':field must be numeric',
        ]
    )
);

$validator->add(
    [
        'height', 
        'width',
    ], 
    new DigitValidator(
        [
            'message' => [
                'height' => 'height must be numeric',
                'width'  => 'width must be numeric',
            ]
        ]
    )
);

• Added Phalcon\Validation\Validator\Date

use Phalcon\Validation\Validator\Date as DateValidator;

$validator->add(
    'date', 
    new DateValidator(
        [
            'format'  => 'd-m-Y',
            'message' => 'The date is not valid',
        ]
    )
);

$validator->add(
    [
        'date',
        'anotherDate',
    ], 
    new DateValidator(
        [
            'format'  => [
                'date'        => 'd-m-Y',
                'anotherDate' => 'Y-m-d',
            ],
            'message' => [
                'date'        => 'The date is invalid',
                'anotherDate' => 'The another date is invalid',
            ]
        ]
    )
);

• Fixed Phalcon\Validation::appendMessage to allow append message to the empty stack #10405

• Added convert option to the Phalcon\Validation\Validator\Uniqueness to convert values to the database lookup #12005#12030

use Phalcon\Validation\Validator\Uniqueness;

$validator->add(
    'username', 
    new Uniqueness(
        [
            'convert' => function (array $values) {
                $values['username'] = strtolower($values['username']);

                return $values;
            }
        ]
    )
);

INTERFACES

• Removed __construct from all interfaces #11410#11441

• Added Phalcon\Cli\DispatcherInterface, Phalcon\Cli\TaskInterface, Phalcon\Cli\RouterInterface and Phalcon\Cli\Router\RouteInterface.

DOCUMENTATION

• Added Indonesian translation #840

VARIOUS

• Added Phalcon\Assets\Manager::exists() to check if collection exists

• Fixed Filter::add method handler #11581

• Fixed issue with radio not being checked when default value is 0 #11358

• Phalcon\Tag::getTitle() shows a title depending on prependTitle and appendTitle

• Using a settable variable for the Mongo Connection Service name instead of a hard coded string #11725

Phalcon\Debug\Dump skip debugging di, fix detecting private/protected properties

• Added new setter Phalcon\Escaper::setDoubleEncode() - to allow setting/disabling double encoding

• Fixed Phalcon\Config::merge for working with php7

PHP7

Phalcon 3.0 supports PHP7! In subsequent releases we will focus on the development of the framework to implove the compatibility and take advantage of the performance enhancements that PHP7 offers. You can install the framework in php7 using the usual installation instructions.

Support

Phalcon 3.0 Long Term Support (LTS) version is out, and it’s packed with new features to help you better create web applications with PHP. This version of the framework will be maintained for 3 years from now.

Acknowledgments

We want to greatly thank everyone who has contributed to accomplish and achieve the completion of this release. Special thanks to our friends around the world that have made possible this release:

Conclusion

Phalcon 3.0 takes a step forward towards a modern framework for PHP. We'll continue working making it more useful and performant for developers. Thank you once more to our wonderful community and users!

Installation

You can install Phalcon 3.0 for either PHP 5.5/5.6/7.0 using the following instructions:

git clone --depth=5 https://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

Windows DLLs are available in the download page.

As always, many thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.0.13 released

We are excited to announce the immediate availability of Phalcon 2.0.13!

This maintenance release number of bug fixes (outlined below). We had 2 more minor releases providing minor fixes since our last blog post, and the CHANGELOG for those is listed below:

2.0.11 (2016-05-04)

  • Fixed Model magic set functionality to maintain variable visibility and utilize setter methods.#11286
  • Added a prepareSave event to model saving
  • Added support for OnUpdate and OnDelete foreign key events to the MySQL adapter
  • Added ability to setLogLevel on multiple logs #10429
  • Fixed regression changes for Phalcon\Translate\Adapter\Gettext::prepareOptions #11429
  • Fixed Phalcon\Mvc\View\Engine\Volt::callMacro bug. Now it's correctly calling call_user_func_array instead of call_user_func
  • Fixed undefined method call Phalcon\Mvc\Collection\Manager::getConnectionService. Now Phalcon\Mvc\Collection::getConnectionService works correctly in according to documentation

2.0.12 (2016-05-16)

  • Fixed regression changes for Phalcon\Mvc\View\Engine\Volt::callMacro #11745
  • Fixed the argument type of Phalcon\Flash::success #11764

2.0.13 (2016-05-19)

  • Restored Phalcon\Text::camelize behavior #11767
  • Used Zephir v0.9.2 to maintain backwards compatibility

Update/Upgrade

Phalcon 2.0.13 can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

Phalcon 2.1.x

As you know, we had plans to release 2.1.0 some weeks ago but we faced some blocking bugs running Phalcon in PHP7 that delayed the launch. Most of these bugs have been fixed and the tests are passing in Travis. We have a few more bugs to address, so we expect to release it soon. If you want to try it out install it from the 2.1.x branch:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
git checkout 2.1.x
zephir build --backend=ZendEngine3

As always, many thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.1.0 RC1 released

We are excited to announce the immediate availability of Phalcon 2.1 RC 1!

This version is our first LTS version and it will be supported 3 years from its final release date. Also, this will be our last release candidate before the final version of Phalcon 2.1.

Phalcon 2.1 introduces a great number of improvements, striving to make Phalcon even a better framework. Final version will be available in two weeks.

NOTE: Some of these changes will break existing Phalcon 2.x applications. Please ensure that you have tested your application sufficiently before migrating your application to 2.1 for production purposes.

Changes in Phalcon 2.1

  • PHP 5.3 is no longer supported
  • Phalcon\Mvc\Model\Validation is now deprecated in favor of Phalcon\Validation
  • The default encrypt mode in Phalcon\Crypt is now changed to MCRYPT_MODE_CFB
  • Changed default hash algorithm in Phalcon\Security to CRYPT_BLOWFISH_Y
  • Changed constructor of Phalcon\Mvc\Model allowing you to pass an array of initialization data
  • Removed support for prefixes strategy in Phalcon\Loader
  • Phalcon\Mvc\View now supports many views directories
  • An absolute path can now be used for Mvc\View::setLayoutsDir
  • Fixed odd view behavior #1933 related to setLayout() and pick()
  • Phalcon\Di is now bound to service closures allowing use Phalcon\Di as $this to access services within the closures
  • If an object is returned after firing the event beforeServiceResolve in Phalcon\Di it overrides the default service localization process
  • Placeholders :controller and :action in Mvc\Router now default to /([\\w0-9\_\-]+) instead of /([\\a-zA-Z0-9\_\-]+)
  • Modifier #u (PCRE_UTF8) is now the default in regex based routes in Mvc\Router
  • Return false from an action disables the view component (same as $this->view->disable())
  • Return a string from an action takes it as the body of the response (same as return $this->response->setContent('Hello world'))
  • Return a string from an Mvc\Micro handler takes it as the body of the response
  • Mvc\Router\Route now escapes characters such as . or + to avoid unexpected behaviors
  • Closures used as handlers inMvc\Micro are now bound to the $app instance
  • Routes now can have an associated callback that can override the default dispatcher and view behavior
  • Phalcon\Mvc\Model now implements JsonSerializable making easy serialize model instances
  • When destructing a Mvc\Model\Manager PHQL cache is cleared
  • Method isSetOption in Phalcon\Validation\ValidatorInterface marked as deprecated. You can now use hasOption instead
  • Added internal check allowEmpty before calling a validator. If it option is true and the value of empty, the validator is skipped
  • Added default header: Content-Type: "application/json; charset=UTF-8" in method Phalcon\Http\Response::setJsonContent
  • Phalcon\Events\Event now implements Phalcon\Events\EventInterface
  • Phalcon\Events\Event::getCancelable renamed to Phalcon\Events\Event::isCancelable
  • Removed Phalcon\Events\Manager::dettachAll in favor of Phalcon\Events\Manager::detachAll
  • Phalcon\Mvc\Model\Criteria::getOrder is renamed to Phalcon\Mvc\Model\Criteria::getOrderBy
  • Added method getOption() in Phalcon\Mvc\Model\RelationInterface
  • Added ability to spoof the HTTP request method
  • Added FULLTEXT index type to Phalcon\Db\Adapter\Pdo\Mysql
  • Fixed the use of the annotation router with namespaced controllers
  • Added Phalcon\Acl\RoleAware and Phalcon\Acl\ResourceAware Interfaces. You can now pass objects to Phalcon\Acl\AdapterInterface::isAllowed as roleName and resourceName, which will be automatically passed to the function defined in Phalcon\Acl\AdapterInterface::allow or Phalcon\Acl\AdapterInterface::deny by type
  • Phalcon\Acl\AdapterInterface::allow and Phalcon\Acl\AdapterInterface::deny have now a 4th argument - function, which will be called when using Phalcon\Acl\AdapterInterface::isAllowed
  • Phalcon\Acl\AdapterInterface::isAllowed has now a 4th argument - parameters; You can pass arguments for function defined in Phalcon\Acl\AdapterInterface:allow or Phalcon\Acl\AdapterInterface::deny as associative array where key is the argument name
  • Added method getActionSuffix() in Phalcon\DispatcherInterface
  • CLI parameters are now handled consistently
  • Added Phalcon\Mvc\Controller\BindModelInterface and associated model type hint loading through dispatcher.
  • Added Phalcon\Dispatcher::hasParam()
  • Phalcon\Cli\Console and Phalcon\Mvc\Application now inherit Phalcon\Application.
  • Fixed afterFetch event not being sent to behaviors
  • Fixed issue with radio not being checked when default value is 0 #11358
  • Fixed issue with Model::__set that was bypassing setters #11286
  • Fixed issue with Model::__set that was setting hidden attributes directly when setters are not declared #11286
  • Added Phalcon\Cli\DispatcherInterface, Phalcon\Cli\TaskInterface, Phalcon\Cli\RouterInterface and Phalcon\Cli\Router\RouteInterface.
  • Added Phalcon\Mvc\Collection::update, Phalcon\Mvc\Collection::create and Phalcon\Mvc\Collection::createIfNotExist
  • Removed __construct from all interfaces #11410
  • Fire the dispatch:beforeException event when there is an exception during dispatching #11458
  • Added OR operator for Phalcon\Mvc\Model\Query\Builder methods: betweenWhere, notBetweenWhere, inWhere and notInWhere
  • Fixed bug of destroy method of Phalcon\Session\Adapter\Libmemcached
  • Added Phalcon\Cache\Backend\Memcache::addServers to enable pool of servers for memcache
  • Added setLastModified method to Phalcon\Http\Response
  • Added Phalcon\Validation\Validator\Date
  • Mcrypt is replaced with openssl in Phalcon\Crypt
  • Removed methods setMode(), getMode(), getAvailableModes() in Phalcon\CryptInterface
  • Added Phalcon\Assets\Manager::exists() to check if collection exists

PHP 7 support

Phalcon 2.1.x has beta PHP7 support, we expect to fix any blocking bug in the next two weeks before the final release. You can try Phalcon running on PHP7 by compiling from the 2.1.x branch using Zephir:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
git checkout 2.1.x
zephir build --backend=ZendEngine3

After this, you only have to add extension=phalcon.so to your php.ini file.

New Package Infrastructure

We would like to share with you, our community, our plans for moving forward with regards to packaging and distributing Phalcon.

We have been researching many options to make the whole process easy, transparent and automated as possible. Our goal is to be able to use a continuous delivery system that will compile and package Phalcon immediately after each release. To achieve this, we chose to use the Packagecloud service to distribute Phalcon binaries.

This move will increase the availability of Phalcon in more Linux operating systems than currently available, and users will be able to use any built-in package manager of their operating system to install the framework. The available operating systems will be:

  • Debian
  • CentOS
  • RedHat
  • Amazon Linux
  • Fedora
  • LinuxMint
  • Oracle Linux
  • Raspbian
  • Scientific Linux
  • Ubuntu
  • elementary OS

In addition to the above, automation will reduce the human interaction currently needed to create each Phalcon distribution.

For the time being, each distribution will be manually compiled by the Phalcon Team. Our goal is not to change the framework and the way it works for the community, but rather the way it is distributed. For that we will ensure that the new delivery mechanism is tested sufficiently, before we fully switch to Packagecloud and deprecate our Launchpad repository.

This move will make Phalcon available to a much wider variety of Linux based operating systems and reduce the time needed to produce those packages.

We will announce in our blog when this change will happen, so for the time being you can keep getting new versions as you have been in the past.

Update/Upgrade

Phalcon 2.1 RC1 can be installed from the 2.1.x branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
git checkout 2.1.x
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
git checkout 2.1.x
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

As always, many thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.0.10 released

We are excited to announce the immediate availability of Phalcon 2.0.10!

This is the tenth maintenance release in the 2.0.x series, adding more fixes
and improvements to make the most of Phalcon.

Changes in 2.0.10

  • ORM: Added support for DATE columns in Oracle
  • Fixed wrong total_items and total_pages in Paginator when the query builder has set groupBy()
  • Fixed Phalcon\Acl\Memory::allow #11210 related to the inconsistent behavior with access specified as string and array
  • Added quoting column in Phalcon\Db\Dialect\MySQL::addColumn when define position of the column
  • Added support to define position of the column in Phalcon\Db\Dialect\MySQL::modifyColumn
  • Fixed Phalcon\Mvc\Model\Query\Builder #11298 related to resetting limit to null
  • Fixed Phalcon\Tag::getTitle #11185. Now a title will be automatically escaped.
  • Fixed Phalcon\Translate\Adapter\Gettext::exists #11310 related to the wrong returned value (always true)
  • Fixed Phalcon\Translate\Adapter\Gettext::setLocale #11311 related to the incorrect setting locale
  • Added ability to persistent connection in Phalcon\Queue\Beanstalk::connect
  • Fixed Phalcon\Http\Response::redirect #11324. Incorrect initialization local array of status codes
  • Fixed cache backends #11322 related to saving number 0
  • Fixed Phalcon\Db\Dialect::escape #11359. Added ability to use the database name with dots.

Update/Upgrade

This version can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

Thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.0.9 released

We are excited to announce the immediate availability of Phalcon 2.0.9!

This is the ninth maintenance release in the 2.0.x series, adding more fixes
and improvements to make the most of Phalcon.

Changes in 2.0.9

  • Added Phalcon\Security\Random::base58 - to generate a random base58 string
  • Added Phalcon\Logger\Adapter::isTransaction() to check whether the logger is currently in transaction mode or not (Phalcon 1.3 behavior)
  • Phalcon\Session\Adapter now closes the session when the adapter is destroyed (Phalcon 1.3 behavior)
  • Fixed fetching of data in modes FETCH_CLASS, FETCH_INTO and FETCH_FUNC in Phalcon\Db
  • Added missing code property in Phalcon\Validation\Message available in Phalcon 1.3.x
  • Added Phalcon\Db\Column::TYPE_TIMESTAMP to allow migrations on these kind of columns
  • Added Phalcon\Db\ColumnInterface::hasDefault to check if a column has a default value declared in its database column definition
  • Fixed determining of default value for column in Phalcon\Db\Dialect\MySQL, Phalcon\Db\Dialect\Sqlite and Phalcon\Db\Dialect\Postgresql classes
  • Now Phalcon\Mvc\Model::__call invokes finders as in __callStatic
  • Fixed Phalcon\Db\Dialect\Postgresql::getColumnDefinition for BIGINT and BOOLEAN data types
  • Fixed BOOLEAN default value in Phalcon\Db\Dialect\Postgresql
  • Added Phalcon\Validation\Validator\CreditCard - validation credit card number using luhn algorithm

Update/Upgrade

This version can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

Thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.0.8 and 2.1 beta 2 released

We are excited to announce the immediate availability of Phalcon 2.0.8 and Phalcon 2.1.0 beta 2!

This is the eighth maintenance release in the 2.0.x series. In regards to Phalcon 2.1,
the second beta introduces bug fixes and new features intended to stabilize our next
major release.

Changes in 2.0.8

  • Added Phalcon\Security\Random::base58 - to generate a random base58 string
  • Added Phalcon\Logger\Adapter::isTransaction() to check whether the logger is currently in transaction mode or not (Phalcon 1.3 behavior)
  • Phalcon\Session\Adapter now closes the session when the adapter is destroyed (Phalcon 1.3 behavior)
  • Fixed fetching of data in modes FETCH_CLASS, FETCH_INTO and FETCH_FUNC in Phalcon\Db
  • Added missing code property in Phalcon\Validation\Message available in Phalcon 1.3.x
  • Added Phalcon\Db\Column::TYPE_TIMESTAMP to allow migrations on these kind of columns
  • Added Phalcon\Db\ColumnInterface::hasDefault to check if a column has a default value declared in its database column definition
  • Fixed determining of default value for column in Phalcon\Db\Dialect\MySQL, Phalcon\Db\Dialect\Sqlite and Phalcon\Db\Dialect\Postgresql classes
  • Now Phalcon\Mvc\Model::__call invokes finders as in __callStatic
  • Fixed Phalcon\Db\Dialect\Postgresql::getColumnDefinition for BIGINT and BOOLEAN data types
  • Fixed BOOLEAN default value in Phalcon\Db\Dialect\Postgresql
  • Added Phalcon\Validation\Validator\CreditCard - validation credit card number using luhn algorithm

Changes in 2.1.0 beta 2

  • Phalcon\Mvc\Model now implements JsonSerializable making easy serialize model instances
  • When destroying a Mvc\Model\Manager object the PHQL cache is clean
  • Method isSetOption in Phalcon\Validation\ValidatorInterface marked as deprecated, please use hasOption
  • Added internal check "allowEmpty" before calling a validator. If it option is true and the value of empty, the validator is skipped
  • Added default header: Content-Type: "application/json; charset=UTF-8" in method Phalcon\Http\Response::setJsonContent
  • Loop structure in Volt now can be passed to macros and functions as loop.self

Last month, important improvements to support PHP7 have been done by the Zephir Team, so we expect to have a usable version of Phalcon for PHP7 soon.

Update/Upgrade

This version can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

Thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.1.0 beta 1 released

We're excited to announce the first beta release of Phalcon 2.1!

The 2.1.x series are going to be supported for a much longer period than previous versions, thus it is marked as our first Long Term Support LTS release!

In the Phalcon 2.0.x series, we introduced a lot of new features as well as bug fixes. Our focus however has always been to keep backwards compatibility with Phalcon 1.3.x series, while at the same time encourage developers to upgrade to 2.0.x. This allowed ample time for developers to adjust their applications to work with the 2.0.x series.

Phalcon 2.1 introduces new features some of them incompatible with previous released versions, so make sure you test your application before upgrading a production system.

We are confident that the changes in this release warrant the upgrade :)

Deprecation for PHP 5.3

Phalcon 2.0.x is the latest series of releases supporting PHP 5.3 (>= 5.3.21). Due to this constraint, we were unable to include some performance enhancements to the framework.

From 2.1.x onwards we are deprecating support for PHP 5.3. We highly encourage developers to upgrade their installations to 5.6, since PHP 7 is just around the corner. We are working on PHP 7 support for Phalcon, but in the meantime the recommended PHP version with Phalcon is 5.6.

Phalcon\Mvc\Model\Validation is now deprecated

Phalcon\Mvc\Model\Validation is now deprecated in favor of Phalcon\Validation. The functionality of both components is merged into one, allowing us to reduce the codebase while offering the same functionality as before.

Previously validations were implemented as follows:

namespace Invo\Models;

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Validator\Email as EmailValidator;
use Phalcon\Mvc\Model\Validator\Uniqueness as UniquenessValidator;

class Users extends Model
{
    public function validation()
    {
        $this->validate(
            new EmailValidator(
                [
                    'field' => 'email',
                ]
            )
        );

        $this->validate(
            new UniquenessValidator(
                [
                    'field'   => 'username',
                    'message' => 'Sorry, That username is already taken',
                ]
            )
        );

        if ($this->validationHasFailed() == true) {
            return false;
        }
    }
}

Introducing Phalcon\Validation, you will need to change the above to:

namespace Invo\Models;

use Phalcon\Mvc\Model;
use Phalcon\Validation;
use Phalcon\Validation\Validator\Email as EmailValidator;
use Phalcon\Validation\Validator\Uniqueness as UniquenessValidator;

class Users extends Model
{
    public function validation()
    {
        $validator = new Validation();

        $validator->add(
            'email', //your field name
            new EmailValidator([
                'model' => $this,
                "message" => 'Please enter a correct email address'
            ])
        );

        $validator->add(
            'username',
            new UniquenessValidator([
                'model' => $this,
                'message' => 'Sorry, That username is already taken',
            ])
        );

        return $this->validate($validator);
    }
}

You will agree that this change makes the code much smaller and easier to read.

Changed the constructor of Phalcon\Mvc\Model

The constructor of model classes has been changed, to allow you to pass an array of initialization data:

$customer = new Customer(
    [
        'name'   => 'Peter',
        'status' => 'Active',
    ]
);

Using this method is the same as calling assign(), any setter available will be used and will fallback to property assignment.

Phalcon\Mvc\View supports many views directories

This has been one of the features that our community requested many times in the past. We are happy to announce that you can use any kind of folder hierarchy with your application for your view files. This is specially useful for reusing views and layouts between modules:

use Phalcon\Mvc\View;

// ...

$di->set(
    'view',
    function () {

        $view = new View();

        $view->setViewsDir(
            [
                '/var/www/htdocs/blog/modules/backend/views/',
                '/var/www/htdocs/blog/common/views/',
            ]
        );

        return $view;
    }
);

Phalcon\Mvc\View now supports absolute paths

An absolute path can now be used on Mvc\View::setLayoutsDir and Mvc\View::setPartialsDir. This allows the use of folders outside the main views folder:

use Phalcon\Mvc\View;

// ...

$di->set(
    'view',
    function () {

        $view = new View();

        $view->setViewsDir(
            [
                '/var/www/htdocs/blog/modules/backend/views/',
                '/var/www/htdocs/blog/common/views/',
            ]
        );

        $view->setLayoutsDir(
            '/var/www/htdocs/common/views/layouts/'
        );

        return $view;
    }
);

Phalcon\Di is now bound to services closures

In the past, we had to pass the dependency injector inside a service closure, if we had to perform some actions inside the closure. Examples of that were accessing the configuration object or the events manager. Now we can use $this to access the Phalcon\Di along with the registered services.

Code before:

use Phalcon\Mvc\Dispatcher;

// ...

$di->set(
    'dispatcher',
     function () use ($di) {
        $eventsManager = $di->getEventsManager();

        $eventsManager->attach(
            'dispatch:beforeException',
            new NotFoundPlugin()
        );

        $dispatcher = new Dispatcher;
        $dispatcher->setEventsManager($eventsManager);

        return $dispatcher;
    }
);

Now you can access services without passing $di:

use Phalcon\Mvc\Dispatcher;

// ...

$di->set(
    'dispatcher',
    function () {
        $eventsManager = $this->getEventsManager();

        $eventsManager->attach(
            'dispatch:beforeException',
            new NotFoundPlugin()
            );

        $dispatcher = new Dispatcher;
        $dispatcher->setEventsManager($eventsManager);
        return $dispatcher;
    }
);

Service Resolve overriding

If an object is returned after firing the event beforeServiceResolve in Phalcon\Di, the returned instance overrides the default service localization process.

The following example shows how to override the creation of the service response from a custom plugin:

use Phalcon\Di;
use Phalcon\Http\Response;
use Phalcon\Events\Manager;

use MyApp\Plugins\ResponseResolverInterceptor;

$di = new Di();

$eventsManager = new EventsManager;

// Intercept service creation
$eventsManager->attach(
    'di',
    new ResponseResolverInterceptor()
);

$di->set('response', Response::class);

$di->setInternalEventsManager($eventsManager);

The plugin can now intercept the creation of services:

namespace MyApp\Plugins;

use Phalcon\Http\Response;

class ResponseResolverInterceptor
{
    private $cache = false;

    public function beforeServiceResolve($event, $di, $parameters)
    {
        // Intercept creation of responses
        if ($parameters['name'] == 'response' && $this->cache == false) {
            $response = new Response();
            $response->setHeader('Cache-Control', 'no-cache, must-revalidate');

            return $response;
        }
    }
}

Disabling the view from an action

Sometimes the view must be disabled by calling $this->view->disable() within an action in order to avoid the Phalcon\Mvc\View component to process the relevant view(s).

Now this much easier; simply return false:

use Phalcon\Mvc\Controller;

class Api extends Controller
{
    public function loginAction()
    {
        if ($this->safeApp->isBanned()) {
            $this->response->setStatusCode(401, "Unauthorized");
            return false;
        }

        // ...
    }
}

Returning a string makes it the body of the response

Return a string from an action takes it as the body of the response:
(same as return $this->response->setContent('Hello world'))

use Phalcon\Mvc\Controller;

class Session extends Controller
{
    public function welcomeAction()
    {
        return '<h1>Hello world!</h1>';
    }
}

This feature is specially handy if Phalcon\Mvc\View\Simple is used instead of Phalcon\Mvc\View:

use Phalcon\Mvc\Controller;

class Session extends Controller
{
    public function welcomeAction($name)
    {
        return $this->view->render(
            'welcome/index',
            [
                'name' => $name,
            ]
        );
    }
}

This feature is also available in Mvc\Micro handlers:

use Phalcon\Mvc\Micro;

$app = new Micro();

// ...

$app->get(
    '/hello/{name}',
    function () {
        return $this->view->render(
            'hello',
            [
                'name' => $name,
            ]
        );
    }
);

Override dispatcher+view behavior in routes

Routes now can have an associated callback that can override the default dispatcher + view behavior:

// Make a redirection if the /help route is matched
$router->add('/help', [])->match(function () {
    return $this->getResponse()->redirect('https://support.google.com/');
});

// Return a string directly from the route
$router->add('/', [])->match(function () {
    return '<h1>It works</h1>';
});

See the full CHANGELOG for Phalcon 2.1.

Help with Testing

This version can be installed from the 2.1.x branch. If you don't have Zephir installed follow these instructions:

git clone https://github.com/phalcon/cphalcon
git checkout 2.1.x
cd cphalcon/ext
sudo ./install

If you have Zephir installed:

git clone https://github.com/phalcon/cphalcon
cd cphalcon/
git checkout 2.1.x
zephir build

We hope that you will enjoy these improvements and additions. We invite you to share your thoughts and questions about this version on Phosphorum.

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.0.7 released

We are excited to announce the release of Phalcon 2.0.7!
This is our seventh release in the 2.0.x series and it contains bug fixes and new features for your enjoyment!

Changes

  • Image\Adapter\Gd::save() no longer fails if the method or the instance is created with a filename without an extension
  • Fixed segfault and implementation of Image\Adapter\Imagick::text()
  • Exceptions thrown in Volt compiler are now Phalcon\Mvc\View\Engine\Exception
  • Now you can import macros from other files using {% include "file.volt" %}
  • Undefined function calls fall back to macro calls in Volt templates
  • Automatic bound parameters in Mvc\Model\Criteria now uses a different prefix
    than Mvc\Model\Query\Builder to avoid collisions
  • Added Cache\Multiple::flush() to flush the cache backends added to the multiple system
  • Fixed Session\Bag::remove()
  • Session\Bag::destroy() eliminates any temporary data in the variables bag
  • afterCreate/afterUpdate are only called if saving related records was successful
  • Added an optional parameter removeData to Session\Adapter::remove() to remove any data in $_SESSION that belongs to the uniqueId or the whole session data
  • Now session variables making use of unique prefixes use # as internal separator
  • Added parameter that changes the default operator for conditions in method Mvc\Model\Criteria::fromImput() #10749
  • Added \Phalcon\Queue\Beanstalk::listTubes() to get list of a tubes
  • Added a fix to avoid that a table present in many sub-queries causes invalid SQL generation
  • Add CookieInterface, update Cookie and Cookies to use this interface - Decoupling Cookies and Cookie - Check Session state before using it in Cookie. #10789
  • Fixed merge of two Phalcon\Config instances that contains object values different than Phalcon\Config compatible instances
  • When creating tables in Postgres, inline PRIMARY keys are now escaped properly #10797
  • Fixed incorrect generation of SELECT COUNT(*) causing unexpected exceptions when phqlLiterals is disabled
  • Added Phalcon\Security\Random - secure random number generator class. Provides secure random number generator which is suitable for generating session key in HTTP cookies, etc

Update/Upgrade

This version can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

Thanks to everyone involved in this release and thanks for choosing Phalcon!

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000

Phalcon 2.0.6 released

We are excited to announce the release of Phalcon 2.0.6!

This version contains mostly bug fixes as well as improvements to the 2.0.x series.

Changes

  • Builds in TravisCI now uses Docker to perform faster builds
  • Added Http\Response::setCache() to easily set cache headers.
  • When a beanstalkd connection is closed, the adapter does not produce a notice anymore
  • Default separator in Text::increment is now _ (underscore)
  • Using tel_field in Volt now generates correct PHP code
  • SQL generated by PostgreSQL dialect in dropTable and dropView is now correct
  • Errors generated in Cache\Backend\Memcached now shows the result code to easily debug problems
  • Fixed LIMIT/OFFSET SQL generation in Mvc\Model\Query\Builder
  • Fixed Logger\Formatter\Line to match 1.3.x behavior
  • Fixed warning when castOnHydrate is true #10648
  • Added name before int/float/numeric/string/bool/null/other variables in Debug\Dump::output
  • Now Validation\Validator\Identical allows both 'accepted' and 'value' as value to keep backwards compatibility
  • Added \Phalcon\Mvc\Model\MetaData\Redis adapter.
  • Added Redis Session adapter
  • Fixed bug in Mvc\Model\Criteria::fromInput preventing it from using renamed columns
  • Fixed bug in Http\Request getRawBody()/getPut() clears input buffer #10694

Update/Upgrade

This version can be installed from the master branch, if you don't have Zephir installed follow these instructions:

git clone http://github.com/phalcon/cphalcon
cd cphalcon/build
sudo ./install

If you have Zephir installed:

git clone http://github.com/phalcon/cphalcon
cd cphalcon
zephir build

Note that running the installation script will replace any version of Phalcon installed before.

Windows DLLs are available in the download page.

See the upgrading guide for more information about upgrading to Phalcon 2.0.x from 1.3.x.

<3 Phalcon Team

01010000011010000110000101101100011000110110111101101110010100000100100001010000