File Manager (Silex + Kendo UI) - Tutorial

A sudden story from the past! Here is how it was. Despite the fact that I am a programmer of a “slightly different sense”, they turned to me with a standard request - to make a site. Usually I don’t undertake such things, but this time I decided to make some money, especially since it was not a business card website or online store, but a normal site with a database of some objects, objects are added, edited, deleted (ala CRUD) and with they need to perform some operations. ABOUT! I thought, yes this is an ideal task for (the name of the framework is hidden) and after all kinds of bookkeeping I immediately got down to business.

Actually, nothing interesting and unusual happened. After some time, the site was shown to the customer. And ... he was pleased. A very unexpected ending to the story.

True, a small request appeared. He did not like the file manager, the one with which you can insert a picture into the article in the article. He wanted it to be somehow easier. And then there are as many as 20 buttons! Yes, and a lot of action. And you just need to upload the picture to the server and paste it on the page. Well, I thought, theirs is the whole Internet, and I myself have made such decisions many times. But one is scary as hell, the other one file at a time downloads, but the third is nothing like, but paid. In general, the story ended quickly, creating a simple file manager from scratch. But somehow I sat, and was sad. And I drank (juice with pulp, of course). And he opened the IDE and away we go ...




I corrected the code, added a bunch of some features there and wrote this article in which I’ll try to tell, unlike a bunch of manuals, I can’t create a blog in any way, but how to make a file manager on Silex + Kendo UI. Without a database, without a viewer and editors, and without other “husks”.

First, I’ll start by trying to explain why I chose these tools (frameworks).

Silex is a microframework about which I have heard a review many times: “So it has no nichrome!”. But this is not true, Silex is a completely logical solution, but it consisted in taking a huge Symfony2 and deleting the vendors folder. Absolutely. After all, they came up with Composer - a “tool” about which a lot has already been written, but he knows how to, based on the contents of the composer.json file, take and download the latest versions of the necessary libraries (vendors - vendors). We need ORM to access the database, we love the TWIG templating engine, we want to store the values ​​in redis. We will write the necessary in composer.json, execute the php composer.phar install command, and here Silex is not so any.
But for the file manager, it fits much better than some other bulky solutions.

We need to decide what we will need from silex:
1) Of course, the solution on the popular framework is already good in itself
2) Work with sessions
3) Work with answers (response and redirect)
4) Twig template engine
I’ll add a little why I like twig so much and strongly encourage others to use it. I am not a typesetter, but very often I have to work in templates (view) in the usual form for php: i.e. use inserts from php. "Php is powerful, it’s a template engine for itself!" - repeat the opposite. That's right, but he is too powerful a template engine. Many times I found myself thinking that I write logic in a template! And this is absolutely impossible! So twig makes you rethink the process of creating templates. It is powerful enough to be able to do a lot, and at the same time, it leaves ideas to “program” in the template.

Well, with the php framework we decided - let it be. Why kendo ui? Is he big? Well yes, he really is not small. But, firstly, the site that I did already used kendo, and secondly, the solution on this JS framework looks beautiful.
What do we need from kendo:
1) window
2) splitter
3) uploader
4) menubar
5) treeview
By the way, if we take third-party js for such purposes, then the solution will not be too small.

Now I will try to describe the operation of the application. I think you can read the code without me, so I will focus on the things that I consider more important.

Response

Symfony2 and of course Silex have a very convenient feature - they allow you to manage outgoing (response) requests. This application actively uses javascript, and js (in particular jquery ajax) may respond differently to the response from the application. In other words, if the ajax function receives a normal response with code 200, it will respond in this way, and if the error is different. For example, the jquery ajax function can handle the onSuccess (200 OK answer) and onError (not 200, but 500, for example) methods (onSuccess and itError recently - done and fail). And with the help of the HttpFoundation \ Response vendor, you can just send an answer with the right code.

Where it is used - we try to save the file (load) in the file system. But the system administrator, something was smart there, and instead of the www-data user, the folder became owned by the root user. So, we cannot save the file - there are not enough rights. We write the received error into the variable $ this-> error. And in the function handler of the action (saving the picture), let's do this:

if ($save->handleUpload($sPath, $_thumbPath)) {
        return new Response('', 200);
} else {
        return new Response($save->getError(), 200);
}


Where, handleUpload - the function that saves the file, if the operation is successful - will return TRUE, otherwise FALSE.

Namespaces

Silex tries to use all the innovations of php, and in particular, actively uses namespaces.
In principle, you can use the usual include, but it’s somehow not kosher. We will use the method that Silex offers, and that, in turn, has recently transferred the function of "registering the address space" to composer.

So. In our file manager, there are two logical parts:
1) work with the file system;
2) saving files and generating thumbnails for images.
Create two classes: class Files {} and class Save {}. Each class will be located in the same file in the folder: / src / Fm / Components. In order for our application to understand where to download these files from, we will write it in composer.json:

"autoload":{
        "psr-0":{
            "Fm" : "src/"
        }
    }


And now we execute the command:
php composer.phar update

Now we can use our classes, but before that we do not forget to declare them
use Fm\Component\Save
use Fm\Component\Files


You can appreciate the charm of using namespaces only in a large application, but nevertheless, you need to try to use the "right" methods. Indeed, it often happens that if you neglect such a seemingly small thing, later it may turn out that the application has grown and it is too late to think about refactoring, and it is cheaper to rewrite it from scratch.

Depency injection

The next feature of the Silex framework is the ubiquitous Depency Injecting. If you heard about it from Symfony2, it might seem that this is some kind of scary and muddy crap that is needed only in Entrprise. And again, this opinion is not true.
1) All texts about DI are completely clumsy promt translation from English documentation, which was generated in phpDocumentaror
2) People who work in this very Entrprise cannot speak in simple words or do not want to, because they know something. IT Buddhists.

Back to DI. The Files () class is used a lot in the code. If you work the old fashioned way, then in each action, you will have to create a new new Files () object. DI allows you to create an object only once:

$app['files'] = function() {
    return new Files();
};


And later already have a copy of it referring to $ app ['files']. But, it is important to remember that:

$app['files']->getFiles($dir); //получаем список файлов в private $_files;
$app['files']->getFolderFiles(); //геттер, возвращает массив $_files;


Doesn't work! Because you need to do this:

$class = $app['files'];
$class->getFiles($dir); //получаем список файлов в private $_files;
$class->getFolderFiles(); //геттер, возвращает массив $_files;


In other words, each time you access $ app ['files'], a new copy of the “service” will be created. You can create a new “service” like this:

$app['some_service'] = $app->share(function () {
    return new Service();
});


Then in the process of executing the application there will always be one copy of it.

The file manager is uploaded to Github .

This article does not cover the kendo ui library. In principle, if there is a desire - you can make a quick inspection of it, with features that affect the theme of the file manager.

PS Although few people read the topic - but still:
ckfinder is not free;
elfinder is just the manager who caused the “stupor” of the customer. It has 24 buttons, without signatures, + actions on the right click;
all these and many other fm are written in another php, here is Silex, and all the application logic in:

/index.php - 11kb
/js/fm.js - 10kb
+ "models":
/ silex / src / Fm / Components / Files.php - 11 kb
/silex/src/Fm/Components/Save.php - 3 kb

Also popular now: