{"action":"created","comment":{"url":"https://api.github.com/repos/sulu-cmf/sulu/pulls/comments/25851526","id":25851526,"diff_hunk":"@@ -12,717 +12,760 @@ define([\n     'sulumedia/collection/medias',\n     'sulumedia/model/collection',\n     'sulumedia/model/media'\n-], function (Collections, Medias, Collection, Media) {\n-\n-        'use strict';\n-\n-        var collectionEditTabs = {\n-                FILES: 'files',\n-                SETTINGS: 'settings'\n-            },\n-\n-            constants = {\n-                lastVisitedCollectionKey: 'last-visited-collection'\n-            },\n-\n-            namespace = 'sulu.media.collections.',\n-\n-            /**\n-             * listens on and changes the view to collections list\n-             * @event sulu.media.collections.list\n-             * @param noReload {Boolean} if false page reloads\n-             */\n-            ROUTE_TO_LIST = function () {\n-                return createEventName.call(this, 'list');\n-            },\n-\n-            /**\n-             * listens on and deletes medias\n-             * @event sulu.media.collections.delete-media\n-             * @param ids {Array} array of ids of the media to delete\n-             * @param afterConfirm {Function} callback to execute after modal has been confirmed\n-             * @param callback {Function} callback to execute after a media got deleted\n-             * @param noDialog {Boolean} if true no dialog will be shown\n-             */\n-            DELETE_MEDIA = function () {\n-                return createEventName.call(this, 'delete-media');\n-            },\n-\n-            /**\n-             * listens on and move medias\n-             * @event sulu.media.collections.move-media\n-             * @param ids {Array} array of ids of the media to delete\n-             * @param collection {Object} collection to move media into\n-             * @param callback {Function} callback to execute after a media got moved\n-             */\n-            MOVE_MEDIA = function () {\n-                return createEventName.call(this, 'move-media');\n-            },\n-\n-            /**\n-             * listens on and reloads a media\n-             * @event sulu.media.collections.reload-single-media\n-             * @param id {String|Number} The id of the media\n-             * @param parameters {Object} parameters to add to the request\n-             * @param callback {Function} callback to pass the result to\n-             */\n-            RELOAD_SINGLE_MEDIA = function () {\n-                return createEventName.call(this, 'reload-single-media');\n-            },\n-\n-            /**\n-             * listens on and reloads multiple media\n-             * @event sulu.media.collections.reload--media\n-             * @param media {Array} An array of media models\n-             * @param parameters {Object} parameters to add to the request\n-             * @param callback {Function} callback to pass the result to\n-             */\n-            RELOAD_MEDIA = function () {\n-                return createEventName.call(this, 'reload-media');\n-            },\n-\n-            /**\n-             * listens on and deletes a collection\n-             * @event sulu.media.collections.delete-collection\n-             * @param id {Number|String} the id of the collection to delete\n-             * @param callback {Function} callback to execute after a media got deleted\n-             */\n-            DELETE_COLLECTION = function () {\n-                return createEventName.call(this, 'delete-collection');\n-            },\n-\n-            /**\n-             * raised after a media got deleted\n-             * @event sulu.media.collections.media-deleted\n-             * @param id {Number|String} the id of the deleted media\n-             */\n-            SINGLE_MEDIA_DELETED = function () {\n-                return createEventName.call(this, 'media-deleted');\n-            },\n-\n-            /**\n-             * raised after a collection got deleted\n-             * @event sulu.media.collections.collection-deleted\n-             * @param id {Number|String} the id of the deleted media\n-             */\n-            COLLECTION_DELETED = function () {\n-                return createEventName.call(this, 'collection-deleted');\n-            },\n-\n-            /**\n-             * raised after a media model got saved\n-             * @event sulu.media.collections.media-saved\n-             * @param {Object} the changed media object\n-             */\n-            MEDIA_SAVED = function () {\n-                return createEventName.call(this, 'media-saved');\n-            },\n-\n-            /**\n-             * listens on loads the media model for an id and forwards it to another component\n-             * @event sulu.media.collections.edit-media\n-             * @param id {Number|String} the id of the media to edit\n-             */\n-            EDIT_MEDIA = function () {\n-                return createEventName.call(this, 'edit-media');\n-            },\n-\n-            /**\n-             * listens on saves a given media\n-             * @event sulu.media.collections.save-media\n-             * @param media {Object|Array} a media object with at least an id property. Can be an array of media objects\n-             * @param callback {Function} a callback-method to execute after all media got saved\n-             */\n-            SAVE_MEDIA = function () {\n-                return createEventName.call(this, 'save-media');\n-            },\n-\n-            /**\n-             * listens on saves a given collection\n-             * @event sulu.media.collections.save-collection\n-             * @param collection {Object} a collection object with at least an id property\n-             * @param callback {Function} callback to call after collection has been saved\n-             */\n-            SAVE_COLLECTION = function () {\n-                return createEventName.call(this, 'save-collection');\n-            },\n-\n-            /**\n-             * listens on and reloads a collection\n-             * @event sulu.media.collections.reload-media\n-             * @param id {String|Number} The id of the collection\n-             * @param parameters {Object} parameters to add to the request\n-             * @param callback {Function} callback to pass the result to\n-             */\n-            RELOAD_COLLECTION = function () {\n-                return createEventName.call(this, 'reload-collection');\n-            },\n-\n-            /**\n-             * emited after a collection entity got changed\n-             * @event sulu.media.collections.collection-changed\n-             * @param {Object} the changed collection object\n-             */\n-            COLLECTION_CHANGED = function () {\n-                return createEventName.call(this, 'collection-changed');\n-            },\n-\n-            /**\n-             * listens on and navigates to collection edit\n-             * @event sulu.media.collections.collection-edit\n-             * @param {Number|String} the id of the collection\n-             * @param {String} the tab to navigate to\n-             */\n-            NAVIGATE_COLLECTION_EDIT = function () {\n-                return createEventName.call(this, 'collection-edit');\n-            },\n-\n-            /**\n-             * listens on and navigates to collection list\n-             * @event sulu.media.collections.collection-list\n-             */\n-            NAVIGATE_COLLECTION_LIST = function () {\n-                return createEventName.call(this, 'collection-list');\n-            },\n-\n-            /**\n-             * listens on and downloads a single media\n-             * @event sulu.media.collections.download-media\n-             */\n-            DOWNLOAD_MEDIA = function () {\n-                return createEventName.call(this, 'download-media');\n-            },\n-\n-            /** returns normalized event names */\n-            createEventName = function (postFix) {\n-                return namespace + postFix;\n-            };\n-\n-        return {\n-\n-            initialize: function () {\n-                // store backbone-models in global backbone-collections\n-                this.collections = new Collections();\n-                this.medias = new Medias();\n-\n-                this.getLocale().then(function (locale) {\n-                    this.locale = locale;\n-                    this.bindCustomEvents();\n-\n-                    if (this.options.display === 'list') {\n-                        this.renderList();\n-                    } else if (this.options.display === 'files') {\n-                        this.renderCollectionEdit({\n-                            activeTab: 'files'\n-                        });\n-                    } else if (this.options.display === 'settings') {\n-                        this.renderCollectionEdit({\n-                            activeTab: 'settings'\n-                        });\n-                    } else {\n-                        throw 'display type wrong';\n-                    }\n-                    this.startMediaEdit();\n+], function(Collections, Medias, Collection, Media) {\n+\n+    'use strict';\n+\n+    var collectionEditTabs = {\n+            FILES: 'files',\n+            SETTINGS: 'settings'\n+        },\n+\n+        constants = {\n+            lastVisitedCollectionKey: 'last-visited-collection'\n+        },\n+\n+        namespace = 'sulu.media.collections.',\n+\n+        /**\n+         * listens on and deletes medias\n+         * @event sulu.media.collections.delete-media\n+         * @param ids {Array} array of ids of the media to delete\n+         * @param afterConfirm {Function} callback to execute after modal has been confirmed\n+         * @param callback {Function} callback to execute after a media got deleted\n+         * @param noDialog {Boolean} if true no dialog will be shown\n+         */\n+        DELETE_MEDIA = function() {\n+            return createEventName.call(this, 'delete-media');\n+        },\n+\n+        /**\n+         * listens on and move medias\n+         * @event sulu.media.collections.move-media\n+         * @param ids {Array} array of ids of the media to delete\n+         * @param collection {Object} collection to move media into\n+         * @param callback {Function} callback to execute after a media got moved\n+         */\n+        MOVE_MEDIA = function() {\n+            return createEventName.call(this, 'move-media');\n+        },\n+\n+        /**\n+         * listens on and move collection\n+         * @event sulu.media.collections.move\n+         * @param id {integer} id of moving collection\n+         * @param collection {Object} collection to move collection into\n+         * @param callback {Function} callback to execute after collection got moved\n+         */\n+        MOVE_COLLECTION = function() {\n+            return createEventName.call(this, 'move');\n+        },\n+\n+        /**\n+         * listens on and reloads a media\n+         * @event sulu.media.collections.reload-single-media\n+         * @param id {String|Number} The id of the media\n+         * @param parameters {Object} parameters to add to the request\n+         * @param callback {Function} callback to pass the result to\n+         */\n+        RELOAD_SINGLE_MEDIA = function() {\n+            return createEventName.call(this, 'reload-single-media');\n+        },\n+\n+        /**\n+         * listens on and reloads multiple media\n+         * @event sulu.media.collections.reload--media\n+         * @param media {Array} An array of media models\n+         * @param parameters {Object} parameters to add to the request\n+         * @param callback {Function} callback to pass the result to\n+         */\n+        RELOAD_MEDIA = function() {\n+            return createEventName.call(this, 'reload-media');\n+        },\n+\n+        /**\n+         * listens on and deletes a collection\n+         * @event sulu.media.collections.delete-collection\n+         * @param id {Number|String} the id of the collection to delete\n+         * @param callback {Function} callback to execute after a media got deleted\n+         */\n+        DELETE_COLLECTION = function() {\n+            return createEventName.call(this, 'delete-collection');\n+        },\n+\n+        /**\n+         * raised after a media got deleted\n+         * @event sulu.media.collections.media-deleted\n+         * @param id {Number|String} the id of the deleted media\n+         */\n+        SINGLE_MEDIA_DELETED = function() {\n+            return createEventName.call(this, 'media-deleted');\n+        },\n+\n+        /**\n+         * raised after a media model got saved\n+         * @event sulu.media.collections.media-saved\n+         * @param {Object} the changed media object\n+         */\n+        MEDIA_SAVED = function() {\n+            return createEventName.call(this, 'media-saved');\n+        },\n+\n+        /**\n+         * listens on loads the media model for an id and forwards it to another component\n+         * @event sulu.media.collections.edit-media\n+         * @param id {Number|String} the id of the media to edit\n+         */\n+        EDIT_MEDIA = function() {\n+            return createEventName.call(this, 'edit-media');\n+        },\n+\n+        /**\n+         * listens on saves a given media\n+         * @event sulu.media.collections.save-media\n+         * @param media {Object|Array} a media object with at least an id property. Can be an array of media objects\n+         * @param callback {Function} a callback-method to execute after all media got saved\n+         */\n+        SAVE_MEDIA = function() {\n+            return createEventName.call(this, 'save-media');\n+        },\n+\n+        /**\n+         * listens on saves a given collection\n+         * @event sulu.media.collections.save-collection\n+         * @param collection {Object} a collection object with at least an id property\n+         * @param callback {Function} callback to call after collection has been saved\n+         */\n+        SAVE_COLLECTION = function() {\n+            return createEventName.call(this, 'save-collection');\n+        },\n+\n+        /**\n+         * listens on and reloads a collection\n+         * @event sulu.media.collections.reload-media\n+         * @param id {String|Number} The id of the collection\n+         * @param parameters {Object} parameters to add to the request\n+         * @param callback {Function} callback to pass the result to\n+         */\n+        RELOAD_COLLECTION = function() {\n+            return createEventName.call(this, 'reload-collection');\n+        },\n+\n+        /**\n+         * emited after a collection entity got changed\n+         * @event sulu.media.collections.collection-changed\n+         * @param {Object} the changed collection object\n+         */\n+        COLLECTION_CHANGED = function() {\n+            return createEventName.call(this, 'collection-changed');\n+        },\n+\n+        /**\n+         * listens on and navigates to collection edit\n+         * @event sulu.media.collections.collection-edit\n+         * @param {Number|String} the id of the collection\n+         * @param {String} the tab to navigate to\n+         */\n+        NAVIGATE_COLLECTION_EDIT = function() {\n+            return createEventName.call(this, 'collection-edit');\n+        },\n+\n+        /**\n+         * listens on and downloads a single media\n+         * @event sulu.media.collections.download-media\n+         */\n+        DOWNLOAD_MEDIA = function() {\n+            return createEventName.call(this, 'download-media');\n+        },\n+\n+        /**\n+         * navigate to a collection when breadcrumb where clicked\n+         * @event sulu.media.collections.breadcrumb-navigate\n+         */\n+        BREADCRUMB_NAVIGATE = function() {\n+            return createEventName.call(this, 'breadcrumb-navigate');\n+        },\n+\n+        /** returns normalized event names */\n+        createEventName = function(postFix) {\n+            return namespace + postFix;\n+        };\n \n-                }.bind(this));\n-            },\n+    return {\n \n-            /**\n-             * Gets the current locale for editing\n-             * @returns {*}\n-             */\n-            getLocale: function () {\n-                var dfd = this.sandbox.data.deferred();\n+        initialize: function() {\n+            // store backbone-models in global backbone-collections\n+            this.collections = new Collections();\n+            this.medias = new Medias();\n \n-                this.sandbox.emit('sulu.media.collections-edit.get-locale', function (locale) {\n-                    dfd.resolve(locale);\n-                }.bind(this));\n+            this.getLocale().then(function(locale) {\n+                this.locale = locale;\n+                this.bindCustomEvents();\n \n                 if (this.options.display === 'list') {\n-                    dfd.resolve(this.sandbox.sulu.user.locale);\n-                }\n-\n-                return dfd.promise();\n-            },\n-\n-            /**\n-             * Helper function to get a media model\n-             * @param id {String|Number} id of the model\n-             * @returns {Object} the backbone model\n-             */\n-            getMediaModel: function (id) {\n-                if (!!this.medias.get(id)) {\n-                    return this.medias.get(id);\n+                    this.renderList();\n+                } else if (this.options.display === 'files') {\n+                    this.renderCollectionEdit({\n+                        activeTab: 'files'\n+                    });\n+                } else if (this.options.display === 'settings') {\n+                    this.renderCollectionEdit({\n+                        activeTab: 'settings'\n+                    });\n                 } else {\n-                    var model = new Media();\n-                    if (!!id) {\n-                        model.set({id: id});\n-                    }\n-                    this.medias.push(model);\n-                    return model;\n+                    throw 'display type wrong';\n                 }\n-            },\n-\n-            /**\n-             * Helper function to get a collection model\n-             * @param id {String|Number} id of the model\n-             * @returns {Object} the backbone model\n-             */\n-            getCollectionModel: function (id) {\n-                if (!!this.collections.get(id)) {\n-                    return this.collections.get(id);\n-                } else {\n-                    var model = new Collection();\n-                    if (!!id) {\n-                        model.set({id: id});\n-                    }\n-                    this.collections.push(model);\n-                    return model;\n+                this.startMediaEdit();\n+            }.bind(this));\n+\n+            this.renderMoveOverlay();\n+        },\n+\n+        renderMoveOverlay: function() {\n+            var $element = this.sandbox.dom.createElement('<div id=\"collection-move-container\"/>');\n+\n+            this.sandbox.dom.append(this.$el, $element);\n+\n+            this.sandbox.start([{\n+                name: 'collections/components/collection-select@sulumedia',\n+                options: {\n+                    el: $element,\n+                    instanceName: 'move-collection',\n+                    title: this.sandbox.translate('sulu.collection.move.overlay-title'),\n+                    rootCollection: true,\n+                    disableIds: [this.options.id],\n+                    disabledChildren: true\n                 }\n-            },\n-\n-            /**\n-             * Bind custom events concerning collections\n-             */\n-            bindCustomEvents: function () {\n-                // navigate to list view\n-                this.sandbox.on(ROUTE_TO_LIST.call(this), function (noReload) {\n-                    this.sandbox.emit('sulu.router.navigate', 'media/collections', !noReload ? true : false, true);\n-                }, this);\n-\n-                // delete media\n-                this.sandbox.on(DELETE_MEDIA.call(this), this.deleteMedia.bind(this));\n-\n-                // move media\n-                this.sandbox.on(MOVE_MEDIA.call(this), this.moveMedia.bind(this));\n-\n-                // delete collection\n-                this.sandbox.on(DELETE_COLLECTION.call(this), this.deleteCollection.bind(this));\n-\n-                // edit a media\n-                this.sandbox.on(EDIT_MEDIA.call(this), this.editMedia.bind(this));\n-\n-                // change/saves a media\n-                this.sandbox.on(SAVE_MEDIA.call(this), this.saveMedia.bind(this));\n-\n-                // change/saves a collection\n-                this.sandbox.on(SAVE_COLLECTION.call(this), this.saveCollection.bind(this));\n-\n-                // reload a collection\n-                this.sandbox.on(RELOAD_COLLECTION.call(this), this.reloadCollection.bind(this));\n-\n-                // reload a media\n-                this.sandbox.on(RELOAD_SINGLE_MEDIA.call(this), this.reloadSingleMedia.bind(this));\n-\n-                // reload multiple media\n-                this.sandbox.on(RELOAD_MEDIA.call(this), this.reloadMedia.bind(this));\n-\n-                // reload multiple media\n-                this.sandbox.on(DOWNLOAD_MEDIA.call(this), this.downloadMedia.bind(this));\n-\n-                // navigate to collection edit\n-                this.sandbox.on(NAVIGATE_COLLECTION_EDIT.call(this), function (collectionId, tab) {\n-                    // default tab is files\n-                    tab = (!!tab) ? tab : 'files';\n-                    this.sandbox.emit('sulu.router.navigate', 'media/collections/edit:' + collectionId + '/' + tab, true, true);\n-                }.bind(this));\n+            }]);\n+        },\n+\n+        /**\n+         * Gets the current locale for editing\n+         * @returns {*}\n+         */\n+        getLocale: function() {\n+            var dfd = this.sandbox.data.deferred();\n+\n+            this.sandbox.emit('sulu.media.collections-edit.get-locale', function(locale) {\n+                dfd.resolve(locale);\n+            }.bind(this));\n+\n+            if (this.options.display === 'list') {\n+                dfd.resolve(this.sandbox.sulu.user.locale);\n+            }\n \n-                // navigate to collection list\n-                this.sandbox.on(NAVIGATE_COLLECTION_LIST.call(this), function () {\n-                    this.sandbox.emit('sulu.router.navigate', 'media/collections', true, true);\n-                }.bind(this));\n-            },\n-\n-            /**\n-             * Downloads a single media\n-             * @param mediaId {Number|String} the id of the media\n-             */\n-            downloadMedia: function(mediaId) {\n-                var media;\n-                // if media exists there is no need to fetch the media again - the local one is up to date\n-                if (!this.medias.get(mediaId)) {\n-                    media = this.getMediaModel(mediaId);\n-                    media.fetch({\n-                        success: function (media) {\n-                            this.sandbox.dom.window.location.href = media.toJSON().url;\n-                        }.bind(this),\n-                        error: function () {\n-                            this.sandbox.logger.log('Error while fetching a single media');\n-                        }.bind(this)\n-                    });\n-                } else {\n-                    media = this.getMediaModel(mediaId);\n-                    this.sandbox.dom.window.location.href = media.toJSON().url;\n+            return dfd.promise();\n+        },\n+\n+        /**\n+         * Helper function to get a media model\n+         * @param id {String|Number} id of the model\n+         * @returns {Object} the backbone model\n+         */\n+        getMediaModel: function(id) {\n+            if (!!this.medias.get(id)) {\n+                return this.medias.get(id);\n+            } else {\n+                var model = new Media();\n+                if (!!id) {\n+                    model.set({id: id});\n                 }\n-            },\n-\n-            /**\n-             * Saves data for an existing collection\n-             * @param data {Object} object with the data to update\n-             * @param callback {Function} callback to call if collection has been saved\n-             */\n-            saveCollection: function (data, callback) {\n-                var collection = this.getCollectionModel(data.id);\n-                collection.set(data);\n-                collection.save(null, {\n-                    success: function (collection) {\n-                        this.sandbox.emit(COLLECTION_CHANGED.call(this), collection.toJSON());\n-                        if (typeof callback === 'function') {\n-                            callback(collection.toJSON());\n-                        }\n-                    }.bind(this),\n-                    error: function () {\n-                        this.sandbox.logger.log('Error while saving collection');\n-                    }.bind(this)\n-                });\n-            },\n-\n-            /**\n-             * Reloads a collection and passes the result to a callback\n-             * @param id {String|Number} The id of the collection\n-             * @param parameters {Object} parameters to add to the request\n-             * @param callback {Function} callback to pass the result to\n-             */\n-            reloadCollection: function (id, parameters, callback) {\n-                var collection = this.getCollectionModel(id);\n-                collection.fetch({\n-                    data: parameters,\n-                    success: function (collection) {\n-                        if (typeof callback === 'function') {\n-                            callback(collection.toJSON());\n-                        }\n-                    }.bind(this),\n-                    error: function () {\n-                        this.sandbox.logger.log('Error while fetching a single collection');\n-                    }.bind(this)\n-                });\n-            },\n-\n-            /**\n-             * Reloads a single media and passes the result to a callback\n-             * @param id {String|Number} The id of the media\n-             * @param parameters {Object} parameters to add to the request\n-             * @param callback {Function} callback to pass the result to\n-             */\n-            reloadSingleMedia: function (id, parameters, callback) {\n-                var media = this.getMediaModel(id);\n+                this.medias.push(model);\n+                return model;\n+            }\n+        },\n+\n+        /**\n+         * Helper function to get a collection model\n+         * @param id {String|Number} id of the model\n+         * @returns {Object} the backbone model\n+         */\n+        getCollectionModel: function(id) {\n+            if (!!this.collections.get(id)) {\n+                return this.collections.get(id);\n+            } else {\n+                var model = new Collection();\n+                if (!!id) {\n+                    model.set({id: id});\n+                }\n+                this.collections.push(model);\n+                return model;\n+            }\n+        },\n+\n+        /**\n+         * Bind custom events concerning collections\n+         */\n+        bindCustomEvents: function() {\n+            // delete media\n+            this.sandbox.on(DELETE_MEDIA.call(this), this.deleteMedia.bind(this));\n+\n+            // move media\n+            this.sandbox.on(MOVE_MEDIA.call(this), this.moveMedia.bind(this));\n+\n+            // move collection\n+            this.sandbox.on(MOVE_COLLECTION.call(this), this.moveCollection.bind(this));\n+\n+            // delete collection\n+            this.sandbox.on(DELETE_COLLECTION.call(this), this.deleteCollection.bind(this));\n+\n+            // edit a media\n+            this.sandbox.on(EDIT_MEDIA.call(this), this.editMedia.bind(this));\n+\n+            // change/saves a media\n+            this.sandbox.on(SAVE_MEDIA.call(this), this.saveMedia.bind(this));\n+\n+            // change/saves a collection\n+            this.sandbox.on(SAVE_COLLECTION.call(this), this.saveCollection.bind(this));\n+\n+            // reload a collection\n+            this.sandbox.on(RELOAD_COLLECTION.call(this), this.reloadCollection.bind(this));\n+\n+            // reload a media\n+            this.sandbox.on(RELOAD_SINGLE_MEDIA.call(this), this.reloadSingleMedia.bind(this));\n+\n+            // reload multiple media\n+            this.sandbox.on(RELOAD_MEDIA.call(this), this.reloadMedia.bind(this));\n+\n+            // reload multiple media\n+            this.sandbox.on(DOWNLOAD_MEDIA.call(this), this.downloadMedia.bind(this));\n+\n+            // navigate to collection edit\n+            this.sandbox.on(NAVIGATE_COLLECTION_EDIT.call(this), function(collectionId, tab) {\n+                // default tab is files\n+                tab = (!!tab) ? tab : 'files';\n+                this.sandbox.emit('sulu.router.navigate', 'media/collections/edit:' + collectionId + '/' + tab, true, true);\n+            }.bind(this));\n+            \n+            this.sandbox.on(BREADCRUMB_NAVIGATE.call(this), function(item) {\n+                this.sandbox.emit('sulu.router.navigate', 'media/collections/edit:' + item.id + '/' + this.options.display);\n+\n+                var url = '/admin/api/collections/' + item.id + '?depth=1';\n+                this.sandbox.emit('husky.data-navigation.collections.set-url', url);\n+            }.bind(this));\n+        },\n+\n+        /**\n+         * Downloads a single media\n+         * @param mediaId {Number|String} the id of the media\n+         */\n+        downloadMedia: function(mediaId) {\n+            var media;\n+            // if media exists there is no need to fetch the media again - the local one is up to date\n+            if (!this.medias.get(mediaId)) {\n+                media = this.getMediaModel(mediaId);\n                 media.fetch({\n-                    data: parameters,\n-                    success: function (media) {\n-                        if (typeof callback === 'function') {\n-                            callback(media.toJSON());\n-                        }\n+                    success: function(media) {\n+                        this.sandbox.dom.window.location.href = media.toJSON().url;\n                     }.bind(this),\n-                    error: function () {\n+                    error: function() {\n                         this.sandbox.logger.log('Error while fetching a single media');\n                     }.bind(this)\n                 });\n-            },\n-\n-            /**\n-             * Reloads multiple media and passes the result to a callback\n-             * @param media {Array} An array of media modesl to reload\n-             * @param parameters {Object} parameters to add to the request\n-             * @param callback {Function} callback to pass the result to\n-             */\n-            reloadMedia: function(media, parameters, callback) {\n-                var mediaList = [];\n-                this.sandbox.util.foreach(media, function(singleMedia) {\n-                    this.reloadSingleMedia(singleMedia.id, parameters, function(updatedSingleMedia) {\n-                        mediaList.push(updatedSingleMedia);\n-                        if (mediaList.length === media.length) {\n-                            callback(mediaList);\n-                        }\n-                    }.bind(this));\n-                }.bind(this));\n-            },\n-\n-            /**\n-             * Deletes an array of media\n-             * @param mediaIds {Array} array of media ids\n-             * @param afterConfirm {Function} callback to execute after modal has been confirmed\n-             * @param callback {Function} callback to execute after deleting a media\n-             * @param noDialog {Boolean} if true no dialog box will be shown\n-             */\n-            deleteMedia: function (mediaIds, afterConfirm, callback, noDialog) {\n-                var media,\n-                    length = mediaIds.length,\n-                    counter = 0,\n-                    finished = false,\n-                    action = function () {\n-                        this.sandbox.util.foreach(mediaIds, function (id) {\n-                            media = this.getMediaModel(id);\n-                            media.destroy({\n-                                success: function () {\n-                                    finished = ++counter === length;\n-                                    if (typeof callback === 'function') {\n-                                        callback(id, finished);\n-                                    } else {\n-                                        this.sandbox.emit(SINGLE_MEDIA_DELETED.call(this), id, finished);\n-                                    }\n-                                }.bind(this),\n-                                error: function () {\n-                                    this.sandbox.logger.log('Error while deleting a single media');\n-                                }.bind(this)\n-                            });\n-                        }.bind(this));\n-                    }.bind(this);\n-\n-                if (noDialog === true) {\n-                    action();\n-                } else {\n-                    this.sandbox.sulu.showDeleteDialog(function (confirmed) {\n-                        if (confirmed === true) {\n-                            if (typeof afterConfirm === 'function') {\n-                                afterConfirm();\n-                            }\n-                            action();\n-                        }\n-                    }.bind(this));\n-                }\n-            },\n-\n-            /**\n-             * Moves an array of media\n-             * @param mediaIds {Array} array of media ids\n-             * @param collection {Object} collection to move media to\n-             * @param callback {Function} callback to execute after moving a media\n-             */\n-            moveMedia: function(mediaIds, collection, callback) {\n-                this.sandbox.util.foreach(mediaIds, function(id) {\n-                    this.sandbox.util.save('/admin/api/media/' + id + '?action=move&destination=' + collection.id, 'POST')\n-                        .then(function() {\n-                            if (typeof callback === 'function') {\n-                                callback(id);\n-                            }\n-                        }.bind(this))\n-                        .fail(function() {\n-                            this.sandbox.logger.log('Error while moving a single media');\n-                        }.bind(this));\n+            } else {\n+                media = this.getMediaModel(mediaId);\n+                this.sandbox.dom.window.location.href = media.toJSON().url;\n+            }\n+        },\n+\n+        /**\n+         * Saves data for an existing collection\n+         * @param data {Object} object with the data to update\n+         * @param callback {Function} callback to call if collection has been saved\n+         */\n+        saveCollection: function(data, callback) {\n+            var collection = this.getCollectionModel(data.id);\n+            collection.set(data);\n+            collection.save(null, {\n+                success: function(collection) {\n+                    this.sandbox.emit(COLLECTION_CHANGED.call(this), collection.toJSON());\n+                    if (typeof callback === 'function') {\n+                        callback(collection.toJSON());\n+                    }\n+                }.bind(this),\n+                error: function() {\n+                    this.sandbox.logger.log('Error while saving collection');\n+                }.bind(this)\n+            });\n+        },\n+\n+        /**\n+         * Reloads a collection and passes the result to a callback\n+         * @param id {String|Number} The id of the collection\n+         * @param parameters {Object} parameters to add to the request\n+         * @param callback {Function} callback to pass the result to\n+         */\n+        reloadCollection: function(id, parameters, callback) {\n+            var collection = this.getCollectionModel(id);\n+            collection.fetch({\n+                data: parameters,\n+                success: function(collection) {\n+                    if (typeof callback === 'function') {\n+                        callback(collection.toJSON());\n+                    }\n+                }.bind(this),\n+                error: function() {\n+                    this.sandbox.logger.log('Error while fetching a single collection');\n+                }.bind(this)\n+            });\n+        },\n+\n+        /**\n+         * Reloads a single media and passes the result to a callback\n+         * @param id {String|Number} The id of the media\n+         * @param parameters {Object} parameters to add to the request\n+         * @param callback {Function} callback to pass the result to\n+         */\n+        reloadSingleMedia: function(id, parameters, callback) {\n+            var media = this.getMediaModel(id);\n+            media.fetch({\n+                data: parameters,\n+                success: function(media) {\n+                    if (typeof callback === 'function') {\n+                        callback(media.toJSON());\n+                    }\n+                }.bind(this),\n+                error: function() {\n+                    this.sandbox.logger.log('Error while fetching a single media');\n+                }.bind(this)\n+            });\n+        },\n+\n+        /**\n+         * Reloads multiple media and passes the result to a callback\n+         * @param media {Array} An array of media modesl to reload\n+         * @param parameters {Object} parameters to add to the request\n+         * @param callback {Function} callback to pass the result to\n+         */\n+        reloadMedia: function(media, parameters, callback) {\n+            var mediaList = [];\n+            this.sandbox.util.foreach(media, function(singleMedia) {\n+                this.reloadSingleMedia(singleMedia.id, parameters, function(updatedSingleMedia) {\n+                    mediaList.push(updatedSingleMedia);\n+                    if (mediaList.length === media.length) {\n+                        callback(mediaList);\n+                    }\n                 }.bind(this));\n-            },\n-\n-            /**\n-             * Deletes a single collection\n-             * @param id {Number|String} the id of the collection to delete\n-             * @param callback {Function} callback to execute after deleting the collection\n-             */\n-            deleteCollection: function (id, callback) {\n-                this.sandbox.sulu.showDeleteDialog(function (confirmed) {\n-                    if (confirmed === true) {\n-                        var collection = this.getCollectionModel(id);\n-                        collection.destroy({\n-                            success: function () {\n+            }.bind(this));\n+        },\n+\n+        /**\n+         * Deletes an array of media\n+         * @param mediaIds {Array} array of media ids\n+         * @param afterConfirm {Function} callback to execute after modal has been confirmed\n+         * @param callback {Function} callback to execute after deleting a media\n+         * @param noDialog {Boolean} if true no dialog box will be shown\n+         */\n+        deleteMedia: function(mediaIds, afterConfirm, callback, noDialog) {\n+            var media,\n+                length = mediaIds.length,\n+                counter = 0,\n+                finished = false,\n+                action = function() {\n+                    this.sandbox.util.foreach(mediaIds, function(id) {\n+                        media = this.getMediaModel(id);\n+                        media.destroy({\n+                            success: function() {\n+                                finished = ++counter === length;\n                                 if (typeof callback === 'function') {\n-                                    callback(id);\n+                                    callback(id, finished);\n                                 } else {\n-                                    this.sandbox.emit(COLLECTION_DELETED.call(this), id);\n+                                    this.sandbox.emit(SINGLE_MEDIA_DELETED.call(this), id, finished);\n                                 }\n                             }.bind(this),\n-                            error: function () {\n-                                this.sandbox.logger.log('Error while deleting a collection');\n+                            error: function() {\n+                                this.sandbox.logger.log('Error while deleting a single media');\n                             }.bind(this)\n                         });\n+                    }.bind(this));\n+                }.bind(this);\n+\n+            if (noDialog === true) {\n+                action();\n+            } else {\n+                this.sandbox.sulu.showDeleteDialog(function(confirmed) {\n+                    if (confirmed === true) {\n+                        if (typeof afterConfirm === 'function') {\n+                            afterConfirm();\n+                        }\n+                        action();\n                     }\n                 }.bind(this));\n-            },\n-\n-            /**\n-             * Edit media. A single one or more at once\n-             * @param data {Number|String|Array} the id of the media or an array of ids\n-             */\n-            editMedia: function (data) {\n-                if (this.sandbox.dom.isArray(data)) {\n-                    if (data.length === 1) {\n-                        this.editSingleMedia(data[0]);\n-                    } else {\n-                        this.editMultipleMedia(data);\n+            }\n+        },\n+\n+        /**\n+         * Moves an array of media\n+         * @param mediaIds {Array} array of media ids\n+         * @param collection {Object} collection to move media to\n+         * @param callback {Function} callback to execute after moving a media\n+         */\n+        moveMedia: function(mediaIds, collection, callback) {\n+            this.sandbox.util.foreach(mediaIds, function(id) {\n+                this.sandbox.util.save('/admin/api/media/' + id + '?action=move&destination=' + collection.id, 'POST')\n+                    .then(function() {\n+                        if (typeof callback === 'function') {\n+                            callback(id);\n+                        }\n+                    }.bind(this))\n+                    .fail(function() {\n+                        this.sandbox.logger.log('Error while moving a single media');\n+                    }.bind(this));\n+            }.bind(this));\n+        },\n+\n+        /**\n+         * Move a collection\n+         * @param collectionId {Integer} id of collection\n+         * @param collection {Object} collection to move collection to\n+         * @param callback {Function} callback to execute after moving the collection\n+         */\n+        moveCollection: function(collectionId, collection, callback) {\n+            this.sandbox.util.save(\n+                [\n+                    '/admin/api/collections/', collectionId,\n+                    '?action=move',\n+                    (!!collection ? '&destination=' + collection.id : '')\n+                ].join(''),\n+                'POST'\n+            ).then(function() {\n+                    if (typeof callback === 'function') {\n+                        callback(collectionId);\n                     }\n+                }.bind(this))\n+                .fail(function() {\n+                    this.sandbox.logger.log('Error while moving a single media');\n+                }.bind(this));","path":"src/Sulu/Bundle/MediaBundle/Resources/public/js/components/collections/main.js","position":1028,"original_position":1028,"commit_id":"ec047fde2f10e41459663d430fab330e8ee5a389","original_commit_id":"ec047fde2f10e41459663d430fab330e8ee5a389","user":{"login":"wachterjohannes","id":1464615,"avatar_url":"https://avatars.githubusercontent.com/u/1464615?v=3","gravatar_id":"","url":"https://api.github.com/users/wachterjohannes","html_url":"https://github.com/wachterjohannes","followers_url":"https://api.github.com/users/wachterjohannes/followers","following_url":"https://api.github.com/users/wachterjohannes/following{/other_user}","gists_url":"https://api.github.com/users/wachterjohannes/gists{/gist_id}","starred_url":"https://api.github.com/users/wachterjohannes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wachterjohannes/subscriptions","organizations_url":"https://api.github.com/users/wachterjohannes/orgs","repos_url":"https://api.github.com/users/wachterjohannes/repos","events_url":"https://api.github.com/users/wachterjohannes/events{/privacy}","received_events_url":"https://api.github.com/users/wachterjohannes/received_events","type":"User","site_admin":false},"body":"where?","created_at":"2015-03-05T09:52:42Z","updated_at":"2015-03-05T09:52:42Z","html_url":"https://github.com/sulu-cmf/sulu/pull/812#discussion_r25851526","pull_request_url":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812","_links":{"self":{"href":"https://api.github.com/repos/sulu-cmf/sulu/pulls/comments/25851526"},"html":{"href":"https://github.com/sulu-cmf/sulu/pull/812#discussion_r25851526"},"pull_request":{"href":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812"}}},"pull_request":{"url":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812","id":29025224,"html_url":"https://github.com/sulu-cmf/sulu/pull/812","diff_url":"https://github.com/sulu-cmf/sulu/pull/812.diff","patch_url":"https://github.com/sulu-cmf/sulu/pull/812.patch","issue_url":"https://api.github.com/repos/sulu-cmf/sulu/issues/812","number":812,"state":"open","locked":false,"title":"Implemented API for nested collection","user":{"login":"wachterjohannes","id":1464615,"avatar_url":"https://avatars.githubusercontent.com/u/1464615?v=3","gravatar_id":"","url":"https://api.github.com/users/wachterjohannes","html_url":"https://github.com/wachterjohannes","followers_url":"https://api.github.com/users/wachterjohannes/followers","following_url":"https://api.github.com/users/wachterjohannes/following{/other_user}","gists_url":"https://api.github.com/users/wachterjohannes/gists{/gist_id}","starred_url":"https://api.github.com/users/wachterjohannes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wachterjohannes/subscriptions","organizations_url":"https://api.github.com/users/wachterjohannes/orgs","repos_url":"https://api.github.com/users/wachterjohannes/repos","events_url":"https://api.github.com/users/wachterjohannes/events{/privacy}","received_events_url":"https://api.github.com/users/wachterjohannes/received_events","type":"User","site_admin":false},"body":"__Tasks:__\r\n\r\n- [x] phpunit test coverage\r\n- [x] behat test coverage\r\n- [ ] gather feedback for my changes\r\n- [ ] submit changes to the documentation\r\n- [x] added changelog line\r\n- [x] nested api for collections\r\n- [x] move collections api\r\n- [x] move collection ui\r\n- [x] nested collection ui\r\n\r\n__New created issues:__\r\n\r\n* New UI for media selection overlay: https://github.com/sulu-cmf/sulu/issues/816\r\n\r\n__Informations:__\r\n\r\n| Q             | A\r\n| ------------- | ---\r\n| Tests pass?   | yes\r\n| Fixed tickets | fixes https://github.com/sulu-cmf/sulu-standard/issues/316\r\n| BC Breaks     | none\r\n| Doc           | none","created_at":"2015-02-10T17:09:39Z","updated_at":"2015-03-05T09:52:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5a56828469e972fbf42e81b412533a6a0e54ebcc","assignee":{"login":"wachterjohannes","id":1464615,"avatar_url":"https://avatars.githubusercontent.com/u/1464615?v=3","gravatar_id":"","url":"https://api.github.com/users/wachterjohannes","html_url":"https://github.com/wachterjohannes","followers_url":"https://api.github.com/users/wachterjohannes/followers","following_url":"https://api.github.com/users/wachterjohannes/following{/other_user}","gists_url":"https://api.github.com/users/wachterjohannes/gists{/gist_id}","starred_url":"https://api.github.com/users/wachterjohannes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wachterjohannes/subscriptions","organizations_url":"https://api.github.com/users/wachterjohannes/orgs","repos_url":"https://api.github.com/users/wachterjohannes/repos","events_url":"https://api.github.com/users/wachterjohannes/events{/privacy}","received_events_url":"https://api.github.com/users/wachterjohannes/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812/commits","review_comments_url":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812/comments","review_comment_url":"https://api.github.com/repos/sulu-cmf/sulu/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sulu-cmf/sulu/issues/812/comments","statuses_url":"https://api.github.com/repos/sulu-cmf/sulu/statuses/ec047fde2f10e41459663d430fab330e8ee5a389","head":{"label":"sulu-cmf:feature/nested-collection","ref":"feature/nested-collection","sha":"ec047fde2f10e41459663d430fab330e8ee5a389","user":{"login":"sulu-cmf","id":5717006,"avatar_url":"https://avatars.githubusercontent.com/u/5717006?v=3","gravatar_id":"","url":"https://api.github.com/users/sulu-cmf","html_url":"https://github.com/sulu-cmf","followers_url":"https://api.github.com/users/sulu-cmf/followers","following_url":"https://api.github.com/users/sulu-cmf/following{/other_user}","gists_url":"https://api.github.com/users/sulu-cmf/gists{/gist_id}","starred_url":"https://api.github.com/users/sulu-cmf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sulu-cmf/subscriptions","organizations_url":"https://api.github.com/users/sulu-cmf/orgs","repos_url":"https://api.github.com/users/sulu-cmf/repos","events_url":"https://api.github.com/users/sulu-cmf/events{/privacy}","received_events_url":"https://api.github.com/users/sulu-cmf/received_events","type":"Organization","site_admin":false},"repo":{"id":13678015,"name":"sulu","full_name":"sulu-cmf/sulu","owner":{"login":"sulu-cmf","id":5717006,"avatar_url":"https://avatars.githubusercontent.com/u/5717006?v=3","gravatar_id":"","url":"https://api.github.com/users/sulu-cmf","html_url":"https://github.com/sulu-cmf","followers_url":"https://api.github.com/users/sulu-cmf/followers","following_url":"https://api.github.com/users/sulu-cmf/following{/other_user}","gists_url":"https://api.github.com/users/sulu-cmf/gists{/gist_id}","starred_url":"https://api.github.com/users/sulu-cmf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sulu-cmf/subscriptions","organizations_url":"https://api.github.com/users/sulu-cmf/orgs","repos_url":"https://api.github.com/users/sulu-cmf/repos","events_url":"https://api.github.com/users/sulu-cmf/events{/privacy}","received_events_url":"https://api.github.com/users/sulu-cmf/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sulu-cmf/sulu","description":"Sulu 2.0 core bundle & components","fork":false,"url":"https://api.github.com/repos/sulu-cmf/sulu","forks_url":"https://api.github.com/repos/sulu-cmf/sulu/forks","keys_url":"https://api.github.com/repos/sulu-cmf/sulu/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sulu-cmf/sulu/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sulu-cmf/sulu/teams","hooks_url":"https://api.github.com/repos/sulu-cmf/sulu/hooks","issue_events_url":"https://api.github.com/repos/sulu-cmf/sulu/issues/events{/number}","events_url":"https://api.github.com/repos/sulu-cmf/sulu/events","assignees_url":"https://api.github.com/repos/sulu-cmf/sulu/assignees{/user}","branches_url":"https://api.github.com/repos/sulu-cmf/sulu/branches{/branch}","tags_url":"https://api.github.com/repos/sulu-cmf/sulu/tags","blobs_url":"https://api.github.com/repos/sulu-cmf/sulu/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sulu-cmf/sulu/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sulu-cmf/sulu/git/refs{/sha}","trees_url":"https://api.github.com/repos/sulu-cmf/sulu/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sulu-cmf/sulu/statuses/{sha}","languages_url":"https://api.github.com/repos/sulu-cmf/sulu/languages","stargazers_url":"https://api.github.com/repos/sulu-cmf/sulu/stargazers","contributors_url":"https://api.github.com/repos/sulu-cmf/sulu/contributors","subscribers_url":"https://api.github.com/repos/sulu-cmf/sulu/subscribers","subscription_url":"https://api.github.com/repos/sulu-cmf/sulu/subscription","commits_url":"https://api.github.com/repos/sulu-cmf/sulu/commits{/sha}","git_commits_url":"https://api.github.com/repos/sulu-cmf/sulu/git/commits{/sha}","comments_url":"https://api.github.com/repos/sulu-cmf/sulu/comments{/number}","issue_comment_url":"https://api.github.com/repos/sulu-cmf/sulu/issues/comments{/number}","contents_url":"https://api.github.com/repos/sulu-cmf/sulu/contents/{+path}","compare_url":"https://api.github.com/repos/sulu-cmf/sulu/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sulu-cmf/sulu/merges","archive_url":"https://api.github.com/repos/sulu-cmf/sulu/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sulu-cmf/sulu/downloads","issues_url":"https://api.github.com/repos/sulu-cmf/sulu/issues{/number}","pulls_url":"https://api.github.com/repos/sulu-cmf/sulu/pulls{/number}","milestones_url":"https://api.github.com/repos/sulu-cmf/sulu/milestones{/number}","notifications_url":"https://api.github.com/repos/sulu-cmf/sulu/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sulu-cmf/sulu/labels{/name}","releases_url":"https://api.github.com/repos/sulu-cmf/sulu/releases{/id}","created_at":"2013-10-18T12:57:02Z","updated_at":"2015-03-03T10:18:39Z","pushed_at":"2015-03-05T08:47:23Z","git_url":"git://github.com/sulu-cmf/sulu.git","ssh_url":"git@github.com:sulu-cmf/sulu.git","clone_url":"https://github.com/sulu-cmf/sulu.git","svn_url":"https://github.com/sulu-cmf/sulu","homepage":"www.sulu.io","size":43197,"stargazers_count":21,"watchers_count":21,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":221,"forks":8,"open_issues":221,"watchers":21,"default_branch":"develop"}},"base":{"label":"sulu-cmf:develop","ref":"develop","sha":"7cfaedb701dade57e0543cbfb1862a9601bb377c","user":{"login":"sulu-cmf","id":5717006,"avatar_url":"https://avatars.githubusercontent.com/u/5717006?v=3","gravatar_id":"","url":"https://api.github.com/users/sulu-cmf","html_url":"https://github.com/sulu-cmf","followers_url":"https://api.github.com/users/sulu-cmf/followers","following_url":"https://api.github.com/users/sulu-cmf/following{/other_user}","gists_url":"https://api.github.com/users/sulu-cmf/gists{/gist_id}","starred_url":"https://api.github.com/users/sulu-cmf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sulu-cmf/subscriptions","organizations_url":"https://api.github.com/users/sulu-cmf/orgs","repos_url":"https://api.github.com/users/sulu-cmf/repos","events_url":"https://api.github.com/users/sulu-cmf/events{/privacy}","received_events_url":"https://api.github.com/users/sulu-cmf/received_events","type":"Organization","site_admin":false},"repo":{"id":13678015,"name":"sulu","full_name":"sulu-cmf/sulu","owner":{"login":"sulu-cmf","id":5717006,"avatar_url":"https://avatars.githubusercontent.com/u/5717006?v=3","gravatar_id":"","url":"https://api.github.com/users/sulu-cmf","html_url":"https://github.com/sulu-cmf","followers_url":"https://api.github.com/users/sulu-cmf/followers","following_url":"https://api.github.com/users/sulu-cmf/following{/other_user}","gists_url":"https://api.github.com/users/sulu-cmf/gists{/gist_id}","starred_url":"https://api.github.com/users/sulu-cmf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sulu-cmf/subscriptions","organizations_url":"https://api.github.com/users/sulu-cmf/orgs","repos_url":"https://api.github.com/users/sulu-cmf/repos","events_url":"https://api.github.com/users/sulu-cmf/events{/privacy}","received_events_url":"https://api.github.com/users/sulu-cmf/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sulu-cmf/sulu","description":"Sulu 2.0 core bundle & components","fork":false,"url":"https://api.github.com/repos/sulu-cmf/sulu","forks_url":"https://api.github.com/repos/sulu-cmf/sulu/forks","keys_url":"https://api.github.com/repos/sulu-cmf/sulu/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sulu-cmf/sulu/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sulu-cmf/sulu/teams","hooks_url":"https://api.github.com/repos/sulu-cmf/sulu/hooks","issue_events_url":"https://api.github.com/repos/sulu-cmf/sulu/issues/events{/number}","events_url":"https://api.github.com/repos/sulu-cmf/sulu/events","assignees_url":"https://api.github.com/repos/sulu-cmf/sulu/assignees{/user}","branches_url":"https://api.github.com/repos/sulu-cmf/sulu/branches{/branch}","tags_url":"https://api.github.com/repos/sulu-cmf/sulu/tags","blobs_url":"https://api.github.com/repos/sulu-cmf/sulu/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sulu-cmf/sulu/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sulu-cmf/sulu/git/refs{/sha}","trees_url":"https://api.github.com/repos/sulu-cmf/sulu/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sulu-cmf/sulu/statuses/{sha}","languages_url":"https://api.github.com/repos/sulu-cmf/sulu/languages","stargazers_url":"https://api.github.com/repos/sulu-cmf/sulu/stargazers","contributors_url":"https://api.github.com/repos/sulu-cmf/sulu/contributors","subscribers_url":"https://api.github.com/repos/sulu-cmf/sulu/subscribers","subscription_url":"https://api.github.com/repos/sulu-cmf/sulu/subscription","commits_url":"https://api.github.com/repos/sulu-cmf/sulu/commits{/sha}","git_commits_url":"https://api.github.com/repos/sulu-cmf/sulu/git/commits{/sha}","comments_url":"https://api.github.com/repos/sulu-cmf/sulu/comments{/number}","issue_comment_url":"https://api.github.com/repos/sulu-cmf/sulu/issues/comments{/number}","contents_url":"https://api.github.com/repos/sulu-cmf/sulu/contents/{+path}","compare_url":"https://api.github.com/repos/sulu-cmf/sulu/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sulu-cmf/sulu/merges","archive_url":"https://api.github.com/repos/sulu-cmf/sulu/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sulu-cmf/sulu/downloads","issues_url":"https://api.github.com/repos/sulu-cmf/sulu/issues{/number}","pulls_url":"https://api.github.com/repos/sulu-cmf/sulu/pulls{/number}","milestones_url":"https://api.github.com/repos/sulu-cmf/sulu/milestones{/number}","notifications_url":"https://api.github.com/repos/sulu-cmf/sulu/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sulu-cmf/sulu/labels{/name}","releases_url":"https://api.github.com/repos/sulu-cmf/sulu/releases{/id}","created_at":"2013-10-18T12:57:02Z","updated_at":"2015-03-03T10:18:39Z","pushed_at":"2015-03-05T08:47:23Z","git_url":"git://github.com/sulu-cmf/sulu.git","ssh_url":"git@github.com:sulu-cmf/sulu.git","clone_url":"https://github.com/sulu-cmf/sulu.git","svn_url":"https://github.com/sulu-cmf/sulu","homepage":"www.sulu.io","size":43197,"stargazers_count":21,"watchers_count":21,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":221,"forks":8,"open_issues":221,"watchers":21,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812"},"html":{"href":"https://github.com/sulu-cmf/sulu/pull/812"},"issue":{"href":"https://api.github.com/repos/sulu-cmf/sulu/issues/812"},"comments":{"href":"https://api.github.com/repos/sulu-cmf/sulu/issues/812/comments"},"review_comments":{"href":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812/comments"},"review_comment":{"href":"https://api.github.com/repos/sulu-cmf/sulu/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sulu-cmf/sulu/pulls/812/commits"},"statuses":{"href":"https://api.github.com/repos/sulu-cmf/sulu/statuses/ec047fde2f10e41459663d430fab330e8ee5a389"}}}}