What you lack in Phalcon?

Hello. I decided to open this topic: What you lack in Phalcon?

Write that you would like to see or change in phalcon.

  1. Generating database schema from annotations in model(so we need a lot more annotations from it) - but i will create it sooner or later.
  2. Better PHP7 support(maybe passing tests at least ?)
  3. Partial models(hydration mode where we can select some columns and still get object of our class and afterFetch fired)


6.1k
  1. Form collection
  2. Session validator - ip, user agent
  3. Navigation menu
  4. Acl - Multiple Inheritance
  5. Form captcha (not recaptcha)


6.1k

Add support for router, set the value of the controller with namespace

$router->add(
    "/",
    array(
        "controller" => "App\Controller\Index",
        'action'     => 'index',
    )
);


17.3k

Better Mail Service.

For #1, make sure you check out https://github.com/SidRoberts/phalcon-seeder first ;)

  1. Generating database schema from annotations in model(so we need a lot more annotations from it) - but i will create it sooner or later.
  2. Better PHP7 support(maybe passing tests at least ?)
  3. Partial models(hydration mode where we can select some columns and still get object of our class and afterFetch fired)

Look i will look into it when i will be creating this, beacause i just want in devtools to generate database schema :) And some other names of functions etc, just annotations like this:

https://github.com/phalcon/cphalcon/issues/11304

For #1, make sure you check out https://github.com/SidRoberts/phalcon-seeder first ;)

  1. Generating database schema from annotations in model(so we need a lot more annotations from it) - but i will create it sooner or later.
  2. Better PHP7 support(maybe passing tests at least ?)
  3. Partial models(hydration mode where we can select some columns and still get object of our class and afterFetch fired)


6.1k

It would be nice to add

$this->request->getFiles() - $_FILES array


6.1k

I think that need to add support RestfulController

edited Mar '16

there is already $this->request->getUploadedFiles() which returns Phalcon\Http\Request\FileInterface[]

It would be nice to add

```php $this->request->getFiles() - $_FILES array ```

RestfulController for what exactly ?



6.1k

When all this will be added, it will be the best framework



6.1k
edited Mar '16

No needs just $_FILES array (not object)

there is already $this->request->getUploadedFiles() which returns Phalcon\Http\Request\FileInterface[]

It would be nice to add

```php $this->request->getFiles() - $_FILES array ```

RestfulController for what exactly ?

edited Mar '16

Using Phalcon\Mvc\Router\Group you can set a namespace https://docs.phalconphp.com/pl/latest/reference/routing.html#groups-of-routes

Add support for router, set the value of the controller with namespace

```php $router->add( "/", array( "controller" => "App\Controller\Index", 'action' => 'index', ) ); ```

Why $_FILES ? Objects are much nicer to handle. If you use framework YOU SHOULDNT EVER ACCES ANY GLOBAL VARIABLE you have methods in framework to access them.



6.1k

RestfulController for what exactly ?

Now we use this

class MyController extends Phalcon\Mvc\Controller
{
      public function indexAction()
      {
              $this->view->disable();
              $response = new \Phalcon\Http\Response();
              $response->setContent(json_encode([
                      'result' => false
              ]));
              return $response;
      }
}
edited Mar '16

Wtf, there is already return $this->response->setJsonContent($array);

Check docs before you implement anything.

And if you need rest you can just disable whole view compomnent when creating di, or disable auto rendering and render/pick only if you need it.



6.1k

But when I try to set a module name, I get error

"Phalcon\Exception - App\Controller\App\Controller\IndexController handler class cannot be loaded"

$router->add(
    "/",
    array(
        'module'     => 'App',
        "controller" => "App\Controller\Index",
        'action'     => 'index',
    )
);

Using Phalcon\Mvc\Router\Group you can set a namespace https://docs.phalconphp.com/pl/latest/reference/routing.html#groups-of-routes

Add support for router, set the value of the controller with namespace

```php $router->add( "/", array( "controller" => "App\Controller\Index", 'action' => 'index', ) ); ```

Why $_FILES ? Objects are much nicer to handle. If you use framework YOU SHOULDNT EVER ACCES ANY GLOBAL VARIABLE you have methods in framework to access them.

edited Mar '16

And how you are registering modules and how looks your namespace in your controller ? For me it's working, for example i have in my app:

file Routes.php in module:

namespace Agregatix\Modules\Comment;


use Phalcon\Mvc\Router\Group;

class Routes extends Group
{
    public function initialize()
    {
        $this->setPaths(['module' => 'comment', 'namespace' => 'Agregatix\Modules\Comment\Controllers']);
        $this->setPrefix('/api/comment');
    }
}

I will add routes later.

And in index.php i have code like this:

    $modules = $application->getModules();
    $modelClasses = [];
    $routeClasses = [];
    $repositoryClasses = [];
    foreach ($modules as $key => $value) {
        $module = ucfirst($key);
        $modelClasses += ["Agregatix\\Modules\\{$module}\\Models" => "../modules/{$key}/models/"];
        $routeClasses += ["Agregatix\\Modules\\{$module}\\Routes" => "../modules/{$key}/Routes.php"];
        $repositoryClasses += ["Agregatix\\Modules\\{$module}\\Repositories" => "../modules/{$key}/repositories"];
    }
    $loader->registerNamespaces($modelClasses);
    $loader->registerNamespaces($repositoryClasses);
    $loader->registerClasses($routeClasses);
    $loader->registerNamespaces([
        'Agregatix\App\Validators' => __APP_DIR__ . '/../app/validators',
        'Agregatix\App\Exceptions' => __APP_DIR__ . '/../app/exceptions',
        'Agregatix\App\Factories' => __APP_DIR__ . '/../app/factories',
        'Agregatix\App\Interfaces' => __APP_DIR__ . '/../app/interfaces',
    ]);
    $loader->register();

    /**
     * Mounting Routes
     */
    foreach ($modules as $key => $value) {
        $module = ucfirst($key);
        $routeClass = "Agregatix\\Modules\\{$key}\\Routes";
        if (class_exists($routeClass)) {
            $routeGroup = new $routeClass;
            $di->get('router')->mount($routeGroup);
        }
    }

And it's working cuz i have similar code in other application :P



6.1k
//index.php
require __DIR__ . '/../app/config/loader.php';
require __DIR__ . '/../app/config/services.php';

$application = new \Phalcon\Mvc\Application();

$application->setDI($di);
$application->registerModules(array(
        'Error' => array(
            'className' => 'Error\Module',
            'path' => '../app/module/error/Module.php'
        ),
        'App' => array(
            'className' => 'App\Module',
            'path' => '../app/module/app/Module.php'
        ),
    ),
);

//loader.php
$loader = new Loader();
$loader->register();

//services.php
$di = new \Phalcon\DI\FactoryDefault();

$di->setShared('router', function () use ($config) {
    return require __DIR__ . '/routes.php';
});

//routes.php
$router = new Phalcon\Mvc\Router(false);
$router->removeExtraSlashes(TRUE);

$router->notFound(array(
    'module' => 'Error',
    'controller' => 'error',
    'action' => 'show404',
));

$router->add("/", array(
    'module' => 'App',
    'controller' => 'App\Controller\Index',
    'action' => 'index',
))->setName('index');


6.1k

I did't use Phalcon\Mvc\Router\Group

edited Mar '16

Then i would recommned to use it :P You need pass a namespace as sepereated parameter

$router->add("/", array(
    'module' => 'App',
    'namespace' => 'App\Controller',
    'controller' => 'index',
    'action' => 'index',
))->setName('index');

That's why im using router groups to dont't have in each route :

    'module' => 'App',
    'namespace' => 'App\Controller',


261

Call controller action from a volt template (for micro too).

Pseudocode:

<div id="recentComments"> {{ pull( 'recentComments', { 'max': 5 } ) }} </div>

Links: Action view helper in Zend, Embedding controllers in Symfony

You can just register controller as a service in di. But i think it's bad behaviour to calling controller from view and should be avoided. You can put logic for getting comments into service or repository and call service/repository from it or just into controller and have propier view.

Call controller action from a volt template (for micro too).

Pseudocode:

<div id="recentComments"> {{ pull( 'recentComments', { 'max': 5 } ) }} </div>

Links: Action view helper in Zend, Embedding controllers in Symfony



6.1k
edited Mar '16

Ok. But why my option does not work? Maybe it's bug?

Then i would recommned to use it :P You need pass a namespace as sepereated parameter

```php $router->add("/", array( 'module' => 'App', 'namespace' => 'App\Controller', 'controller' => 'index', 'action' => 'index', ))->setName('index'); ```

That's why im using router groups to dont't have in each route :

``` 'module' => 'App', 'namespace' => 'App\Controller', ```



6.1k

It automatically adds to the controller - "{module}\Controller\{MyControllerName}Controller"

$router->add("/", array(
    'module' => 'App',
    'controller' => 'App\Controller\Index',
    'action' => 'index',
))->setName('index');

Router creates the name of the controller that is "App\Controller\App\Controller\IndexController"



6.1k

I think it is useful to add CallbackValidator. In which we are going to build the validation logic. Now I create each time a new Validator for this.

$element->addValidators(array(
    new Callback(array(
        'message' => 'Error'
        'callback' => function (Validation $validator, $attribute) {
            $value = $validator->getValue($attribute);

            ...

            return true or false;
        },
    ))
);
edited Mar '16

By default it's looking for a namespace App/Controller, and it's getting controller class which is what you provided in controller + Controller.

Controller is controller name without namespace, just add namespace and that's it.

Why you just dont create your own validator ? ....



6.1k
edited Mar '16

Now I use a controller without a namespace. What is it for - this is for acl

Yes. Now I create own validators. But, if there were CallbackValidator - it would be easier

But it would be wrong. You want your own validation - implement own validator, CallbackValidator is just for lazy programmer.



6.1k

Maybe. The simpler the faster

I would like to have option for Volt to minify final templates. Like Smarty has :)

Apart from that everything is perfect for me <3

edited Mar '16

How about this?:

$di->setShared(
    "view",
    function () use ($di) {
        $view = new \Phalcon\Mvc\View();

        $view->setViewsDir("views/web/");

        $view->setLayoutsDir("_layouts/");

        $view->registerEngines(
            [
                ".volt" => "volt"
            ]
        );



        $eventsManager = $di->getShared("eventsManager");

        $eventsManager->attach(
            "view:afterRender",
            function(\Phalcon\Events\Event $event, \Phalcon\Mvc\ViewInterface $view) {
                $content = $view->getContent();

                $content = preg_replace("/\s+/", " ", $content);

                $view->setContent($content);
            }
        );


        $view->setEventsManager($eventsManager);



        return $view;
    }
);

I would like to have option for Volt to minify final templates. Like Smarty has :)

Apart from that everything is perfect for me <3

It'd be nice to be able to echo development/debugging text in controllers without needing to exit to see it, if the output buffering scope could be narrowed to where the template file were loaded as opposed to the controller level.



6.1k

I also want this

It'd be nice to be able to echo development/debugging text in controllers without needing to exit to see it, if the output buffering scope could be narrowed to where the template file were loaded as opposed to the controller level.