Upload big files to s3 by URL

Recently I needed to upload files to s3 having URL. Unfortunately I didn’t find a way how can I do that with native AWS php sdk. So I needed to provide either file or file body Upload an Object Using the AWS SDK for PHP . I didn’t want to care about temp files. So the easiest solution that came up to my head were

// @see https://github.com/2amigos/resource-manager/
$body = @get_file_content($url);
Yii::app()->resourceManager->save($body, $path, $options);

That worked fine, I also could get file size and mime type having file body. Maybe not very elegant but it worked. Until…

Continue reading

RBAC in Meteor

Meteor development fascinated me. So I continue to play with it. And again I found the case that made me think that I can try to do that a little better. So let’s talk about access control in meteor js.

Meteor allows us to control low level mongo operations via collection.allow and collection.deny. But obviously that it’s not convenient because there’s no way how could I check certain right before actual DB operation. I mean I cannot check if user with “author” role can update its own article.

Ok let’s see what can we do to improve situation with access control in meteor.

Continue reading

Meteor pagination

I was intrigued by meteor  and continue to play with it. Remember my previous post Meteor js first impressions

Be ready that even for the most common things you won’t have existed tools. Or you’ll need to spend much more efforts in comparison with you favorite language/framework.

Today I will tell you about one of such examples – pagination in meteor js.

Continue reading

Meteor.js first impressions

Continue to write and learn server javascript. Recently I had a chance to read “Discover meteor” book and would like to share my first impressions about meteor.js


When I first knew about meteor.js from their promo video it looked fantastic. But I understood that it’s too young. Recently I’ve got an email that they launch stable 1.0 version. And they kindly provide their book(although for a limited time). So I didn’t miss opportunity to grab and read it.

Continue reading

Socket.io how rooms work. And another chat example.

I continue to learn nodejs and socket.io. Today I will explain how do socket.io rooms work. Since for me it’s was quite difficult to understand in details what is it and how it work.

And yes still I’m consider myself not a pro in nodejs and socket.io. So this articles addressed to developers who is also just started their node way.

Ok Go. If we look at socket.io rooms docs  we will find the info how to use rooms but there’s no way to understand HOW it works.

In fact it’s quite straightforward. But let’s see it in details. And we need start from io object. What is it?

var io = require('socket.io')(http);


As you see io keeps info about all connected sockets. This means that you can access socket object if you know it’s ID.

var socket = io.sockets.connected[socketId];

So every socket has it’s own ID. It is generated for each new socket. Now let’s look at socket instance connected to one room.


As you see default socket ID automatically added to rooms.  Therefore when we need to send message to sockets in certain room…

io.sockets.to(chat.room).emit('message', {message: "details"});

(as I can assume) Socket.IO just go through the socket.rooms of the connected sockets and selects sockets that has specified room id. Easy? I think yes. But I must admit I spent some time to get this point.

I hope this could be useful. Also looking ahead I published another nodejs chat example using socket.io you can check it out. This could be a good start point to create your own chat with blackjack.



Crop image before upload

Let’s talk about cropping and resizing today. This quite common task on any web app. And as a rule there are 2 issues with image size.

original image is too big and it doesn’t make sense to return original to client. We need to make it smaller.
image size is not proportional i.e. width is much bigger than height or vice versa.

Dynamically resize images.

Let’s think how we can solve issue #1. The easiest solution is resize image on upload. And then return to client resized images. This will works fine until you need to get same image with bigger or smaller size. We can use browser resizing but you know it sucks. This lead us to decision that allow us to return image with different sizes on fly.

For example we can use such URLs:

You got the idea, right? We will check do we have image with required size in cache if yes- just return it, otherwise create and return. We keep the originals and can easily clean cache folder.

With php we can use https://github.com/avalanche123/Imagine nice library that allows you to make various actions with your images.

Cropping images.

We can use suggested logic but still we have an issue with proportions. For example I’m uploading my another selfie. And I’m not the best photographer. What do we get using logic described below.


Resizing libraries don’t know how to crop your image and will use center and provided proportions to crop your image. As a result you’ll get image like this. But where is my mouth? :)

In such examples when user uploads his avatar or image is quite important and you need to get best of it you can combine first approach with manual cropping.

There’s a dozen of cropping plugins http://www.jqueryrain.com/demo/jquery-crop-image-plugin/ but they work in pretty similar way. They allow use to crop image and then will provide width, height and x,y  points.  Personally I used this one http://fengyuanchen.github.io/cropper/

Finally I provide a piece of javascript code that I used. Ok so you click “Update avatar” we ask user to provide image. After that show popup with cropping dialog. Ask user to crop image and send received data – image, and cropping params to server (x, y, width, height). On server crop the image – save original and then using original cropped image return copies of different sizes.

<!-- our trigger -->
<div class="fileinput-wrapper">
    <button class="block-btn btn text-uppercase btn-primary browse-files fileinput-button">
        Change Icon
        <input type="hidden" name="Profile[avatar_url]" value="">
        <input type="file" id="profile-avatar_url" class="change_profile_avatar" name="Profile[avatar_url]" data-id="70">
        <input type="hidden" id="profile-crop_params" name="Profile[crop_params]" value="">

<!-- cropper dialog -->
<div class="modal fade" style="" id="crop-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">&times;</span>
                    <span class="sr-only">Close</span>
                <h4 class="modal-title" id="myModalLabel">Crop Image</h4>
            <div class="modal-body">
                <div class="eg-main">
                    <div class="eg-wrapper" id="cropper_original_wrapper">

                    <div class="eg-preview clearfix">
                        <h3>Large Preview</h3>
                        <div class="preview preview-md"></div>
                    <div class="eg-preview clearfix">
                        <h3>Small Preview</h3>
                        <div class="preview preview-xs"></div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="save_profile_avatar">CROP & FINISH</button>
                <button type="button" class="btn btn-inverse" data-dismiss="modal">Cancel</button>
 function initAvatarUpdate() {
            dataType: 'json',
            add: function (e, data) {
                var $element = $(this);
                data.url = "/profile/update?id=" + $element.data("id");
                if (data.files && data.files[0]) {
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        var newImg = $("<img>", {"class": "cropper", "src": e.target.result});

                    $("#save_profile_avatar").off('click').on('click', function () {
                        return false;
            done: function (e, data) {
                var newSrc = data._response.result.model.fileUrl;
                $(this).closest('.profile-avatar').find("img").attr("src", newSrc);
                $("#profile_avatar").trigger("profile_changed", [ $(this).data("id"), newSrc])

        function initCropper($element) {
            var $cropper = $(".cropper")
                aspectRatio: 1,
                    x: 1,
                    y: 1,
                    width: 500,
                    height: 500
                preview: ".preview",
                // autoCrop: false,
                // dragCrop: false,
                // modal: false,
                // moveable: false,
                // resizeable: false,
                // maxWidth: 480,
                // maxHeight: 270,
                // minWidth: 160,
                // minHeight: 90,
                done: function(data) {
                        "x": data.x,
                        "y": data.y,
                        "width": data.width,

Finally we got


Javascript module initialization

Today we gonna work with javascript modules. What is it and why do we need to use this approach.

Nothing special – it’s logically separated pieces of your javascript. Wait but I can add my javascript to views where they need it and it will be separated from other views where it’s useless. I don’t have so much JS in my app.

php and js spaghetti

You know… it sucks… it looks like spaghetti code. You mix javascript and php.  And say very big “thank you” for PhpStorm that allows you to separate and highlight javascript.

Ok, so let’s try to separate view from javascript. From the example below I still need to get some data from backend side($typeLink). Sometimes we need to pass some constant or URL. I’d suggest to forget about passing that from backend side. I’m a great supporter of “API First” approach. After my openmed project where I did only the API and we have separate frontend web application that interacted with API I must admin it’s extremely cool. You don’t need to take care about view you are concentrated only on logic. But this is another story. Perhaps I’ll write about that later. Ok we digress… so my piece of advise – try to separate js from your app as much as possible, try to make it independent.

At this point we can move all our javascript code to js files and include all of them. But here we face with some problems. First your javascript still is absolutely unstructured. The increasing of javascript will exacerbate this problem. So let’s add some logic to our javascript put logic related to posts to javascript post module.

Yii2 comes with updated javasctipt module structure. Check it out  read comments. You can use this approach for your own app.

// initially you create your main application module that will
// load all his child modules
myapp = (function ($) {
    'use strict';

    var pub = {
        initModule: function (module) {
            if (module.isActive === undefined || module.isActive) {
                if ($.isFunction(module.init)) {
                $.each(module, function () {
                    if ($.isPlainObject(this)) {
        init: function () {
            // common for all you project javascript logic
            // whatever you want
    // define private functions
    function initLayoutComponents() {

    return pub;

jQuery(document).ready(function () {

// in other files you can define child modules
if (typeof myapp == "undefined" || !myapp) {
    var myapp = {};

myapp.post = (function ($) {

    var pub = {
        isActive: true,
        init: function () {

    function initPostComments() {
    return pub;

OK now we have structured javascript. That located separately from our views. That a good point. But there other issue that we have is – have we gonna include this files.

  • We can include all javascript or even better concatenate it in one file and include once. It will be cached and work much faster. Did you notice isActive param for javasctipt modules. if all modules have it equals true it means that we gonna execute all our javascript. And in most cases we don’t need to do that. Module could init components that currently not in our page. Some page has map, some has comments widget etc. So we need to take care about dynamic module initialization.
  • OR we need to include specific javascript module (or file) for specific page. But this approach even worse since you still need to take care about dynamic includes but lost all profits from caching.

Then I’ll tell you about 2 approaches how you could do that. The easiest one is  just include what you need in your views.

$this->registerJs('myapp.post.isActive = true;', $this::POS_END);
$this->registerJs('myapp.author.isActive = true;', $this::POS_END);

The advantage of such approach that you have full control on what do you include. But I’m pretty sure that in most cases you don’t need such level of control. Using convention over configuration principle you can adjust that for all you controller you’ll have specific module for all contoler’s action you have the function inside your module or another module like controller_action.js. Using this assertion you can easily add some helper for yii and initiate modules base on current route.

Finally for a change I will add one more example. Where I will initiate module base on data-attributes of body. I have rails project so you’ll have coffee script 😉



'use strict'

appRunner =
  exec: (controller, action = "init") ->
    ns = window.app

    if controller != "" && ns[controller] && typeof ns[controller][action] == "function"

  init: ()  ->
    body = document.body
    controller = body.getAttribute( "data-controller" )
    action = body.getAttribute( "data-action" )

    appRunner.exec(controller, action)

window.app.common =
  init: () ->


As you can see here you have some common for your app logic and module with methods per your actions.

Resume: don’t mix js and PHP/Ruby/Whatever. Keep your code clean. Thanks.

Socket IO authorization

I’d like to finish my story about my experiments with nodejs and socket.io. Check out my previous post http://radzserg.com/2014/07/01/socket-io-1-0-emitting-events-from-php/ .The last thing that I wanted to do is authorization. So imagine the following task we want to get updates for specific organization. My idea was quite simple in this case we can send authorization data (username:password or oauth token) to server plus send extra param like organization id

// let's add this param on frontend 
 var socket = io('http://localhost:8000', {
    query: "token=[oauth token]&organizationId=" + organizationId,
    transports: ['websocket']

Let’s add DB service that actually will perform authorization

var config = require('./src/config.json')
var pg = require('pg')
client = new pg.Client(config.pg.cdn);
client.connect(function (error) {
    if (error) {
        return console.error('could not connect to postgres', error);

var dbService = require('./src/services/postgres_service.js')(client);

io.set('authorization', function (handshakeData, cb) {
    dbService.isUserAuthorized(handshakeData._query, function (result, error) {
        if (error) {
            return cb(error, false);
        return cb(null, result);

io.on('connection', function (socket) {
    // if we pass authorization join socket to organization room 
    socket.join("organization." + socket.request._query.organizationId);

An example of DB service could looks like this

module.exports = function (client) {

    return {
        isUserAuthorized: function (data, next) {
            var token = data.token ? data.token : null;
            if (!token) {
                return next(false, "Token must be specified");
            var organizationId = data.organizationId ? data.organizationId : null;
            if (!organizationId) {
                return next(false, "organizationId must be specified");

            var sql;
            sql = 'SELECT user_id FROM oauth_access_tokens WHERE access_token = $1 AND expires > NOW()';
            var query = client.query(sql, [token], function (error, result) {
                if (error) {
                    return next(false, error);
                var userId = typeof result.rows[0] !== 'undefined' ? result.rows[0]['user_id'] : null;
                if (!userId) {
                    return next(false);
                // then required queries to check if user has access to required organization. 
                // ... 
                return next(true)              

Finally on PHP side we also can send events to specific room

$this->_emitter()->in("organization.{$orgnizationId}")->emit("news", [
     'data' => $data

For now that’s it. Make a pause with nodejs. Although it was nice to play with it.