diff --git a/README.md b/README.md
index b97ef99..66934dc 100644
--- a/README.md
+++ b/README.md
@@ -1,69 +1,17 @@
-Symfony Standard Edition
-========================
-Welcome to the Symfony Standard Edition - a fully-functional Symfony2
-application that you can use as the skeleton for your new applications.
-For details on how to download and get started with Symfony, see the
-[Installation][1] chapter of the Symfony Documentation.
+```shell
+npm install -g less
+```
-What's inside?
---------------
+...
-The Symfony Standard Edition is configured with the following defaults:
+```shell
+php app/console braincrafted:bootstrap:install
+```
- * An AppBundle you can use to start coding;
+...
- * Twig as the only configured template engine;
-
- * Doctrine ORM/DBAL;
-
- * Swiftmailer;
-
- * Annotations enabled for everything.
-
-It comes pre-configured with the following bundles:
-
- * **FrameworkBundle** - The core Symfony framework bundle
-
- * [**SensioFrameworkExtraBundle**][6] - Adds several enhancements, including
- template and routing annotation capability
-
- * [**DoctrineBundle**][7] - Adds support for the Doctrine ORM
-
- * [**TwigBundle**][8] - Adds support for the Twig templating engine
-
- * [**SecurityBundle**][9] - Adds security by integrating Symfony's security
- component
-
- * [**SwiftmailerBundle**][10] - Adds support for Swiftmailer, a library for
- sending emails
-
- * [**MonologBundle**][11] - Adds support for Monolog, a logging library
-
- * [**AsseticBundle**][12] - Adds support for Assetic, an asset processing
- library
-
- * **WebProfilerBundle** (in dev/test env) - Adds profiling functionality and
- the web debug toolbar
-
- * **SensioDistributionBundle** (in dev/test env) - Adds functionality for
- configuring and working with Symfony distributions
-
- * [**SensioGeneratorBundle**][13] (in dev/test env) - Adds code generation
- capabilities
-
-All libraries and bundles included in the Symfony Standard Edition are
-released under the MIT or BSD license.
-
-Enjoy!
-
-[1]: http://symfony.com/doc/2.7/book/installation.html
-[6]: http://symfony.com/doc/2.7/bundles/SensioFrameworkExtraBundle/index.html
-[7]: http://symfony.com/doc/2.7/book/doctrine.html
-[8]: http://symfony.com/doc/2.7/book/templating.html
-[9]: http://symfony.com/doc/2.7/book/security.html
-[10]: http://symfony.com/doc/2.7/cookbook/email.html
-[11]: http://symfony.com/doc/2.7/cookbook/logging/monolog.html
-[12]: http://symfony.com/doc/2.7/cookbook/assetic/asset_management.html
-[13]: http://symfony.com/doc/2.7/bundles/SensioGeneratorBundle/index.html
+```shell
+php app/console assetic:dump
+```
\ No newline at end of file
diff --git a/app/AppKernel.php b/app/AppKernel.php
index 9be1531..bb83ba1 100644
--- a/app/AppKernel.php
+++ b/app/AppKernel.php
@@ -19,6 +19,7 @@ class AppKernel extends Kernel
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new DT\Bundle\GeshiBundle\DTGeshiBundle(),
+ new Braincrafted\Bundle\BootstrapBundle\BraincraftedBootstrapBundle(),
new Skobkin\Bundle\CopyPasteBundle\SkobkinCopyPasteBundle(),
);
diff --git a/app/DoctrineMigrations/Version20150303224825.php b/app/DoctrineMigrations/Version20150303224825.php
new file mode 100644
index 0000000..4460679
--- /dev/null
+++ b/app/DoctrineMigrations/Version20150303224825.php
@@ -0,0 +1,22 @@
+addSql('UPDATE copypastes SET secret=NULL WHERE secret=\'\'');
+ }
+
+ public function down(Schema $schema)
+ {
+ $this->addSql('UPDATE copypastes SET secret=\'\' WHERE secret=NULL');
+ }
+}
diff --git a/app/DoctrineMigrations/Version20150305184842.php b/app/DoctrineMigrations/Version20150305184842.php
new file mode 100644
index 0000000..4eac22a
--- /dev/null
+++ b/app/DoctrineMigrations/Version20150305184842.php
@@ -0,0 +1,23 @@
+addSql('UPDATE copypastes SET date_expire=NULL WHERE date_expire=\'0000-00-00 00:00:00\'');
+
+ }
+
+ public function down(Schema $schema)
+ {
+ $this->addSql('UPDATE copypastes SET date_expire=\'0000-00-00 00:00:00\' WHERE date_expire=NULL');
+ }
+}
diff --git a/app/DoctrineMigrations/Version20150316014139.php b/app/DoctrineMigrations/Version20150316014139.php
new file mode 100644
index 0000000..d28ba5c
--- /dev/null
+++ b/app/DoctrineMigrations/Version20150316014139.php
@@ -0,0 +1,32 @@
+ is_enabled
+ * - is_preferred added
+ */
+class Version20150316014139 extends AbstractMigration
+{
+ public function up(Schema $schema)
+ {
+ $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
+
+ $this->addSql('ALTER TABLE languages CHANGE enabled is_enabled TINYINT(1) NOT NULL');
+ $this->addSql('ALTER TABLE languages ADD is_preferred TINYINT(1) NOT NULL');
+ $this->addSql('CREATE INDEX idx_preferred ON languages (is_preferred)');
+ }
+
+ public function down(Schema $schema)
+ {
+ $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
+
+ $this->addSql('ALTER TABLE languages CHANGE is_enabled enabled TINYINT(1) NOT NULL');
+ $this->addSql('ALTER TABLE languages DROP is_preferred');
+ $this->addSql('DROP INDEX idx_preferred ON languages');
+ }
+}
diff --git a/app/Resources/translations/messages.ru.xliff b/app/Resources/translations/messages.ru.xliff
new file mode 100644
index 0000000..576199b
--- /dev/null
+++ b/app/Resources/translations/messages.ru.xliff
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+ paste_add_form_text
+ Текст
+
+
+ paste_add_form_description
+ Описание
+
+
+ paste_add_form_file_name
+ Имя файла
+
+
+ paste_add_form_author
+ Автор
+
+
+ paste_add_form_expire
+ Удалить через
+
+
+ paste_add_form_private
+ Секретно
+
+
+ paste_add_form_language
+ Язык
+
+
+ Create
+ Создать
+
+
+ paste_view_tab_view
+ Просмотр
+
+
+ paste_view_tab_edit
+ Правка
+
+
+ paste_show_qr_show
+ Показать QR
+
+
+ paste_show_download
+ Скачать
+
+
+ 5 minutes
+ 5 минут
+
+
+ 1 hour
+ 1 час
+
+
+ 3 hours
+ 3 часа
+
+
+ 12 hours
+ 12 часов
+
+
+ 1 day
+ 1 день
+
+
+ 1 week
+ 1 неделя
+
+
+ 1 month
+ 1 месяц
+
+
+ 3 months
+ 3 месяца
+
+
+ 6 months
+ 6 месяцев
+
+
+ 1 year
+ 1 год
+
+
+ Never
+ Никогда
+
+
+
+
\ No newline at end of file
diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig
index bafd28d..54bb649 100644
--- a/app/Resources/views/base.html.twig
+++ b/app/Resources/views/base.html.twig
@@ -1,13 +1,52 @@
-
-
-
-
- {% block title %}Welcome!{% endblock %}
- {% block stylesheets %}{% endblock %}
-
-
-
- {% block body %}{% endblock %}
- {% block javascripts %}{% endblock %}
-
-
+{% extends '::layout.html.twig' -%}
+
+{%- block css -%}
+ {{- parent() -}}
+
+{% endblock %}
+{% block javascript %}
+ {{- parent() -}}
+
+{% endblock %}
+
+{%- block header -%}
+
+
+
+{%- endblock -%}
+
+{%- block sidebar -%}
+ {{ render(controller('SkobkinCopyPasteBundle:CopyPaste:sidebar')) }}
+{%- endblock -%}
+
+{% block content %}{% endblock %}
diff --git a/app/Resources/views/layout.html.twig b/app/Resources/views/layout.html.twig
new file mode 100644
index 0000000..8bbbd95
--- /dev/null
+++ b/app/Resources/views/layout.html.twig
@@ -0,0 +1,45 @@
+
+
+
+ {%- block head -%}
+ {% block title %}CopyPaste{% endblock %}
+
+
+ {%- block css -%}
+
+ {%- endblock -%}
+ {# HTML5 Shim and Respond.js add IE8 support of HTML5 elements and media queries #}
+ {% include 'BraincraftedBootstrapBundle::ie8-support.html.twig' %}
+ {%- endblock -%}
+
+
+ {% block body %}
+
+ {% block containter %}
+
+ {% block header %}{% endblock %}
+
+
+
+
+ {% block sidebar %}{% endblock %}
+
+
+ {% block content %}{% endblock %}
+
+
+
+
+ {% block footer %}{% endblock %}
+
+ {% endblock %}
+
+
+ {% block javascript %}
+
+ {# Include all JavaScripts, compiled by Assetic #}
+
+ {% endblock %}
+ {% endblock %}
+
+
\ No newline at end of file
diff --git a/app/Resources/views/sidebar.html.twig b/app/Resources/views/sidebar.html.twig
new file mode 100644
index 0000000..9be9cee
--- /dev/null
+++ b/app/Resources/views/sidebar.html.twig
@@ -0,0 +1,12 @@
+
+
+
{{ 'sidebar_title' | trans() }}
+
+
+
diff --git a/app/config/config.yml b/app/config/config.yml
index b916725..804aaaa 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -5,7 +5,7 @@ imports:
framework:
#esi: ~
- #translator: { fallbacks: ["%locale%"] }
+ translator: { fallbacks: ["%locale%"] }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
@@ -37,12 +37,32 @@ assetic:
bundles: [ ]
#java: /usr/bin/java
filters:
+ less:
+ node: "%nodejs_executable%"
+ node_paths: %nodejs_paths%
+ apply_to: "\.less$"
cssrewrite: ~
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
+braincrafted_bootstrap:
+ output_dir: bootstrap
+ assets_dir: %kernel.root_dir%/../vendor/twbs/bootstrap
+ jquery_path: %kernel.root_dir%/../vendor/components/jquery/jquery.js
+ less_filter: less
+ fonts_dir: %kernel.root_dir%/../web/bootstrap/fonts
+ auto_configure:
+ assetic: true
+ twig: true
+ knp_menu: true
+ knp_paginator: true
+ customize:
+ variables_file: ~
+ bootstrap_output: %kernel.root_dir%/Resources/less/bootstrap.less
+ bootstrap_template: BraincraftedBootstrapBundle:Bootstrap:bootstrap.less.twig
+
# Doctrine Configuration
doctrine:
dbal:
diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist
index 1da778f..497b294 100644
--- a/app/config/parameters.yml.dist
+++ b/app/config/parameters.yml.dist
@@ -18,3 +18,8 @@ parameters:
# A secret key that's used to generate certain security-related tokens
secret: ThisTokenIsNotSoSecretChangeIt
+
+ # Other stuff
+ nodejs_executable: /usr/bin/node
+ nodejs_paths: [/usr/lib/node_modules/]
+
\ No newline at end of file
diff --git a/composer.json b/composer.json
index f675302..474c990 100644
--- a/composer.json
+++ b/composer.json
@@ -23,7 +23,10 @@
"doctrine/doctrine-migrations-bundle": "2.1.*@dev",
"doctrine/doctrine-fixtures-bundle": "2.2.*",
"theodordiaconu/geshi": "dev-master",
- "theodordiaconu/geshi-bundle" : "dev-master"
+ "theodordiaconu/geshi-bundle" : "dev-master",
+ "braincrafted/bootstrap-bundle": "dev-master",
+ "twbs/bootstrap": "3.3.*@dev",
+ "components/jquery": "dev-master"
},
"require-dev": {
"sensio/generator-bundle": "~2.3"
diff --git a/composer.lock b/composer.lock
index 071deca..b263cff 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,110 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "e36598c346f19a7d683f1c1f3d58399f",
+ "hash": "06492598a20c478faba66c1691e8490c",
"packages": [
+ {
+ "name": "braincrafted/bootstrap-bundle",
+ "version": "dev-master",
+ "target-dir": "Braincrafted/Bundle/BootstrapBundle",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/braincrafted/bootstrap-bundle.git",
+ "reference": "2dc17466f95a035869b51c845024f6a92bc1d6d1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/braincrafted/bootstrap-bundle/zipball/2dc17466f95a035869b51c845024f6a92bc1d6d1",
+ "reference": "2dc17466f95a035869b51c845024f6a92bc1d6d1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/console": "~2.3",
+ "symfony/finder": "~2.3",
+ "symfony/form": "~2.3",
+ "symfony/framework-bundle": "~2.3",
+ "symfony/twig-bundle": "~2.3"
+ },
+ "require-dev": {
+ "knplabs/knp-menu": "~2.0@alpha",
+ "knplabs/knp-menu-bundle": "~2.0@alpha",
+ "knplabs/knp-paginator-bundle": "dev-master",
+ "mockery/mockery": "0.9.*",
+ "phpunit/phpunit": "3.7.*",
+ "symfony/assetic-bundle": "~2.3"
+ },
+ "suggest": {
+ "knplabs/knp-menu": "Required to use KnpMenuBundle.",
+ "knplabs/knp-menu-bundle": "BraincraftedBootstrapBundle styles the menus provided by KnpMenuBundle.",
+ "knplabs/knp-paginator-bundle": "BraincraftedBootstrapBundle styles the pagination provided by KnpPaginatorBundle.",
+ "twbs/bootstrap": "Twitter Bootstrap provides the assets (images, CSS and JS)"
+ },
+ "type": "symfony-bundle",
+ "autoload": {
+ "psr-0": {
+ "Braincrafted\\Bundle\\BootstrapBundle": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Florian Eckerstorfer",
+ "email": "florian@eckerstorfer.co",
+ "homepage": "http://florian.ec"
+ }
+ ],
+ "description": "BraincraftedBootstrapBundle integrates Bootstrap into Symfony2 by providing templates, Twig extensions, services and commands.",
+ "keywords": [
+ "bootstrap"
+ ],
+ "time": "2015-01-31 10:32:31"
+ },
+ {
+ "name": "components/jquery",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/components/jquery.git",
+ "reference": "f8edb647d1833fd5d57410ab70860f03534cb2e8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/components/jquery/zipball/f8edb647d1833fd5d57410ab70860f03534cb2e8",
+ "reference": "f8edb647d1833fd5d57410ab70860f03534cb2e8",
+ "shasum": ""
+ },
+ "type": "component",
+ "extra": {
+ "component": {
+ "scripts": [
+ "jquery.js"
+ ],
+ "files": [
+ "jquery.min.js",
+ "jquery.min.map",
+ "jquery-migrate.js",
+ "jquery-migrate.min.js"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "John Resig",
+ "email": "jeresig@gmail.com"
+ }
+ ],
+ "description": "jQuery JavaScript Library",
+ "homepage": "http://jquery.com",
+ "time": "2014-12-23 06:48:45"
+ },
{
"name": "doctrine/annotations",
"version": "v1.2.3",
@@ -816,12 +918,12 @@
"source": {
"type": "git",
"url": "https://github.com/doctrine/migrations.git",
- "reference": "058a4635ac9b80a5b1997df28a754e64b1425a1d"
+ "reference": "312fb5939d5b9dbd66e515374533933e7c5cc8a6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/migrations/zipball/058a4635ac9b80a5b1997df28a754e64b1425a1d",
- "reference": "058a4635ac9b80a5b1997df28a754e64b1425a1d",
+ "url": "https://api.github.com/repos/doctrine/migrations/zipball/312fb5939d5b9dbd66e515374533933e7c5cc8a6",
+ "reference": "312fb5939d5b9dbd66e515374533933e7c5cc8a6",
"shasum": ""
},
"require": {
@@ -866,7 +968,7 @@
"database",
"migrations"
],
- "time": "2015-02-19 08:13:05"
+ "time": "2015-03-02 18:28:52"
},
{
"name": "doctrine/orm",
@@ -1626,12 +1728,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/symfony.git",
- "reference": "755ea09a440c1b8ea560e403b442fc9f53e0ae93"
+ "reference": "12cf04f8f341573a146cdc32722f72ae2deb0579"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/symfony/zipball/755ea09a440c1b8ea560e403b442fc9f53e0ae93",
- "reference": "755ea09a440c1b8ea560e403b442fc9f53e0ae93",
+ "url": "https://api.github.com/repos/symfony/symfony/zipball/12cf04f8f341573a146cdc32722f72ae2deb0579",
+ "reference": "12cf04f8f341573a146cdc32722f72ae2deb0579",
"shasum": ""
},
"require": {
@@ -1735,7 +1837,7 @@
"keywords": [
"framework"
],
- "time": "2015-03-02 10:21:01"
+ "time": "2015-03-03 08:32:45"
},
{
"name": "theodordiaconu/geshi",
@@ -1817,6 +1919,57 @@
],
"time": "2013-03-29 12:54:06"
},
+ {
+ "name": "twbs/bootstrap",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twbs/bootstrap.git",
+ "reference": "ddd09f6fe773c4a99929c169b80882ed955a6227"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twbs/bootstrap/zipball/ddd09f6fe773c4a99929c169b80882ed955a6227",
+ "reference": "ddd09f6fe773c4a99929c169b80882ed955a6227",
+ "shasum": ""
+ },
+ "replace": {
+ "twitter/bootstrap": "self.version"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jacob Thornton",
+ "email": "jacobthornton@gmail.com"
+ },
+ {
+ "name": "Mark Otto",
+ "email": "markdotto@gmail.com"
+ }
+ ],
+ "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
+ "homepage": "http://getbootstrap.com",
+ "keywords": [
+ "JS",
+ "css",
+ "framework",
+ "front-end",
+ "less",
+ "mobile-first",
+ "responsive",
+ "web"
+ ],
+ "time": "2015-03-03 06:03:42"
+ },
{
"name": "twig/extensions",
"version": "v1.2.0",
@@ -1984,7 +2137,10 @@
"doctrine/migrations": 20,
"doctrine/doctrine-migrations-bundle": 20,
"theodordiaconu/geshi": 20,
- "theodordiaconu/geshi-bundle": 20
+ "theodordiaconu/geshi-bundle": 20,
+ "braincrafted/bootstrap-bundle": 20,
+ "twbs/bootstrap": 20,
+ "components/jquery": 20
},
"prefer-stable": false,
"prefer-lowest": false,
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Controller/CopypasteController.php b/src/Skobkin/Bundle/CopyPasteBundle/Controller/CopypasteController.php
new file mode 100644
index 0000000..c815ffd
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Controller/CopypasteController.php
@@ -0,0 +1,154 @@
+createCreateForm($paste);
+ $form->handleRequest($request);
+
+ if ($form->isValid()) {
+ $em = $this->getDoctrine()->getManager();
+
+ if ($form->get('private')->getData()) {
+ // Private paste
+ $paste->setSecret(substr(md5($paste->getText()), 0, 16));
+ }
+
+ $expire = (int) $form->get('expire')->getData();
+ //var_dump($expire); exit();
+ if ($expire) {
+ $dateExpire = new \DateTime();
+ $dateExpire->add(new \DateInterval('PT' . $expire . 'S'));
+ $paste->setDateExpire($dateExpire);
+ }
+
+ $paste->setIp($request->getClientIp());
+
+ $em->persist($paste);
+ $em->flush();
+
+ if ($paste->isPrivate()) {
+ return $this->redirect($this->generateUrl('copypaste_show_private', ['id' => $paste->getId(), 'secret' => $paste->getSecret()]));
+ } else {
+ return $this->redirect($this->generateUrl('copypaste_show_public', ['id' => $paste->getId()]));
+ }
+ }
+
+ throw new $this->createAccessDeniedException('Sorry :(');
+ }
+
+ /**
+ * Creates a form to create a Copypaste entity.
+ *
+ * @param Copypaste $entity The entity
+ *
+ * @return Form The form
+ */
+ private function createCreateForm(Copypaste $entity)
+ {
+ $form = $this->createForm(new CopypasteType(), $entity, [
+ 'action' => $this->generateUrl('copypaste_create'),
+ 'method' => 'POST',
+ ]);
+
+ $form->add('submit', 'submit', array('label' => 'Create'));
+
+ return $form;
+ }
+
+ /**
+ * Displays a form to create a new Copypaste entity.
+ *
+ * @return Response
+ */
+ public function newAction()
+ {
+ $paste = new Copypaste();
+ $createForm = $this->createCreateForm($paste);
+
+ return $this->render('SkobkinCopyPasteBundle:Copypaste:new.html.twig', [
+ 'entity' => $paste,
+ 'form_create' => $createForm->createView(),
+ ]);
+ }
+
+ /**
+ * Finds and displays a Copypaste entity.
+ *
+ * @return Response
+ */
+ public function showAction($id, $secret)
+ {
+ $em = $this->getDoctrine()->getManager();
+
+ /* @var $paste Copypaste */
+ $paste = $em->getRepository('SkobkinCopyPasteBundle:Copypaste')->findOneBy([
+ 'id' =>$id,
+ 'secret' => $secret
+ ]);
+
+ if (!$paste) {
+ throw $this->createNotFoundException('Unable to find copypaste.');
+ }
+
+ $editForm = $this->createCreateForm($paste);
+
+ /* @var $highlighter GeshiHighlighter */
+ $highlighter = $this->get('dt_geshi.highlighter');
+
+ $highlightedCode = $highlighter->highlight($paste->getText(), $paste->getLanguage()->getCode(), function(GeSHi $geshi) {
+ $geshi->set_header_type(GESHI_HEADER_PRE);
+ $geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS);
+ });
+
+ return $this->render('SkobkinCopyPasteBundle:Copypaste:show.html.twig', [
+ 'paste' => $paste,
+ 'highlighted_text' => $highlightedCode,
+ 'form_create' => $editForm->createView(),
+ ]);
+ }
+
+ /**
+ * Main page
+ *
+ * @return Response
+ */
+ public function sidebarAction()
+ {
+ $em = $this->getDoctrine()->getManager();
+
+ $pastes = $em->getRepository('SkobkinCopyPasteBundle:Copypaste')->findBy(
+ ['secret' => null],
+ ['id' => 'DESC'],
+ // @todo move to the config
+ 15
+ );
+
+ return $this->render('::sidebar.html.twig', ['pastes' => $pastes]);
+ }
+
+
+}
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Entity/Copypaste.php b/src/Skobkin/Bundle/CopyPasteBundle/Entity/Copypaste.php
index ed58077..071be71 100644
--- a/src/Skobkin/Bundle/CopyPasteBundle/Entity/Copypaste.php
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Entity/Copypaste.php
@@ -3,17 +3,16 @@
namespace Skobkin\Bundle\CopyPasteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* Copypaste
*
- * @ORM\Table(
- * name="copypastes",
- * indexes={
- * @ORM\Index(name="idx_expire", columns={"date_expire"})
- * }
- * )
+ * @ORM\Table(name="copypastes", indexes={
+ * @ORM\Index(name="idx_expire", columns={"date_expire"})
+ * })
* @ORM\Entity
+ * @ORM\HasLifecycleCallbacks()
*/
class Copypaste
{
@@ -38,7 +37,7 @@ class Copypaste
*
* @ORM\Column(name="description", type="text", nullable=true)
*/
- private $description;
+ private $description = null;
/**
* @var Language
@@ -53,14 +52,14 @@ class Copypaste
*
* @ORM\Column(name="file_name", type="string", length=128, nullable=true)
*/
- private $fileName;
+ private $fileName = null;
/**
* @var string
*
* @ORM\Column(name="author", type="string", length=48, nullable=true)
*/
- private $author;
+ private $author = null;
/**
* @var \DateTime
@@ -74,11 +73,12 @@ class Copypaste
*
* @ORM\Column(name="date_expire", type="datetime", nullable=true)
*/
- private $dateExpire;
+ private $dateExpire = null;
/**
* @var string
*
+ * @Assert\Ip
* @ORM\Column(name="ip", type="string", length=48, nullable=false)
*/
private $ip;
@@ -88,9 +88,15 @@ class Copypaste
*
* @ORM\Column(name="secret", type="string", length=16, nullable=true)
*/
- private $secret;
-
+ private $secret = null;
+ /**
+ * @ORM\PrePersist
+ */
+ public function prePersist()
+ {
+ $this->datePublished = new \DateTime();
+ }
/**
* Get id
@@ -101,6 +107,11 @@ class Copypaste
{
return $this->id;
}
+
+ public function __toString()
+ {
+ return $this->id;
+ }
/**
* Set text
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Entity/Language.php b/src/Skobkin/Bundle/CopyPasteBundle/Entity/Language.php
index 8ef60a1..8eaa8b0 100644
--- a/src/Skobkin/Bundle/CopyPasteBundle/Entity/Language.php
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Entity/Language.php
@@ -7,13 +7,11 @@ use Doctrine\ORM\Mapping as ORM;
/**
* Language
*
- * @ORM\Table(
- * name="languages",
- * indexes={
- * @ORM\Index(name="idx_enabled", columns={"enabled"}),
- * @ORM\Index(name="idx_code", columns={"code"})
- * }
- * )
+ * @ORM\Table(name="languages", indexes={
+ * @ORM\Index(name="idx_enabled", columns={"is_enabled"}),
+ * @ORM\Index(name="idx_preferred", columns={"is_preferred"}),
+ * @ORM\Index(name="idx_code", columns={"code"})
+ * })
* @ORM\Entity
*/
class Language
@@ -40,13 +38,20 @@ class Language
* @ORM\Column(name="code", type="string", length=24, nullable=false)
*/
private $code;
+
+ /**
+ * @var boolean
+ *
+ * @ORM\Column(name="is_preferred", type="boolean", nullable=false)
+ */
+ private $isPreferred = false;
/**
* @var boolean
*
- * @ORM\Column(name="enabled", type="boolean", nullable=false)
+ * @ORM\Column(name="is_enabled", type="boolean", nullable=false)
*/
- private $enabled;
+ private $isEnabled;
@@ -59,6 +64,11 @@ class Language
{
return $this->id;
}
+
+ public function __toString()
+ {
+ return $this->name;
+ }
/**
* Set name
@@ -86,7 +96,7 @@ class Language
/**
* Set code
*
- * @param string $file
+ * @param string $code
* @return Lang
*/
public function setCode($code)
@@ -107,35 +117,47 @@ class Language
}
/**
- * Set enabled
+ * Set isEnabled
*
- * @param boolean $enabled
+ * @param boolean $isEnabled
* @return Lang
*/
- public function setEnabled($enabled)
+ public function setIsEnabled($isEnabled)
{
- $this->enabled = $enabled;
+ $this->isEnabled = $isEnabled;
return $this;
}
/**
- * Get enabled
+ * Get isEnabled
*
* @return boolean
*/
- public function getEnabled()
+ public function getIsEnabled()
{
- return $this->enabled;
+ return $this->isEnabled;
}
/**
- * Check if language is enabled
+ * Get isPreferred
*
* @return boolean
*/
- public function isEnabled()
+ function getIsPreferred()
{
- return $this->enabled;
+ return $this->isPreferred;
+ }
+
+ /**
+ * Set isPreferred
+ *
+ * @param boolean $isPreferred
+ */
+ function setIsPreferred($isPreferred)
+ {
+ $this->isPreferred = $isPreferred;
+
+ return $this;
}
}
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Form/CopypasteType.php b/src/Skobkin/Bundle/CopyPasteBundle/Form/CopypasteType.php
new file mode 100644
index 0000000..c1d69a4
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Form/CopypasteType.php
@@ -0,0 +1,90 @@
+add('text', 'textarea', ['label' => 'paste_add_form_text'])
+ ->add('description', 'textarea', [
+ 'label' => 'paste_add_form_description',
+ 'required' => false,
+ ])
+ ->add('fileName', 'text', [
+ 'label' => 'paste_add_form_file_name',
+ 'required' => false,
+ ])
+ ->add('author', 'text', [
+ 'label' => 'paste_add_form_author',
+ 'required' => false,
+ ])
+ ->add('expire', 'choice', [
+ 'label' => 'paste_add_form_expire',
+ 'mapped' => false,
+ // @todo move to config
+ 'choices' => [
+ 300 => '5 minutes',
+ 3600 => '1 hour',
+ 10800 => '3 hours',
+ 43200 => '12 hours',
+ 86400 => '1 day',
+ 604800 => '1 week',
+ 2419200 => '1 month',
+ 7257600 => '3 months',
+ 14515200 => '6 months',
+ 29030400 => '1 year',
+ 0 => 'Never',
+ ]
+ ])
+ ->add('private', 'checkbox', [
+ 'label' => 'paste_add_form_private',
+ 'required' => false,
+ 'mapped' => false
+ ])
+ ->add('language', 'entity', [
+ 'label' => 'paste_add_form_language',
+ 'class' => 'Skobkin\Bundle\CopyPasteBundle\Entity\Language',
+ 'query_builder' => function (EntityRepository $repo) {
+ /* @var $qb QueryBuilder */
+ return $repo->createQueryBuilder('lang')
+ ->where('lang.isEnabled = :enabled')
+ ->addOrderBy('lang.isPreferred', 'DESC')
+ ->addOrderBy('lang.code')
+ ->setParameter('enabled', true);
+ },
+ //'preferred_choices' => []
+ ])
+ ->add('actions', 'form_actions')
+ ;
+ }
+
+ /**
+ * @param OptionsResolverInterface $resolver
+ */
+ public function setDefaultOptions(OptionsResolverInterface $resolver)
+ {
+ $resolver->setDefaults([
+ 'data_class' => 'Skobkin\Bundle\CopyPasteBundle\Entity\Copypaste'
+ ]);
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return 'skobkin_bundle_copypastebundle_copypaste';
+ }
+}
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing.yml b/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing.yml
index 8b13789..8e4a1d7 100644
--- a/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing.yml
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing.yml
@@ -1 +1,3 @@
-
+skobkin_copy_paste:
+ resource: "@SkobkinCopyPasteBundle/Resources/config/routing/copypaste.yml"
+ prefix: /
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing/copypaste.yml b/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing/copypaste.yml
new file mode 100644
index 0000000..45938d3
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/config/routing/copypaste.yml
@@ -0,0 +1,21 @@
+copypaste_show_public:
+ path: /{id}
+ defaults: { _controller: "SkobkinCopyPasteBundle:Copypaste:show", secret: null }
+ requirements:
+ id: \d+
+
+copypaste_show_private:
+ path: /{id}/{secret}
+ defaults: { _controller: "SkobkinCopyPasteBundle:Copypaste:show" }
+ requirements:
+ id: \d+
+ secret: \w{16}
+
+copypaste_new:
+ path: /
+ defaults: { _controller: "SkobkinCopyPasteBundle:Copypaste:new" }
+
+copypaste_create:
+ path: /create
+ defaults: { _controller: "SkobkinCopyPasteBundle:Copypaste:create" }
+ methods: POST
\ No newline at end of file
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/css/base.css b/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/css/base.css
new file mode 100644
index 0000000..bdfb38b
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/css/base.css
@@ -0,0 +1,44 @@
+/*
+ Created on : Mar 3, 2015, 6:53:42 PM
+ Author : Alexey Skobkin
+*/
+
+html {
+ position: relative;
+ min-height: 100%;
+}
+
+body {
+ /* Margin bottom by footer height */
+ margin-bottom: 60px;
+ padding-top: 70px;
+}
+
+.navbar-brand {
+ font-weight: bold;
+}
+
+/* @todo Fix crutches and bycicles */
+.editor-head button[type="submit"] {
+ margin-top: 24px;
+}
+
+.editor-description {
+ margin-top: 10px;
+}
+
+.editor-head .form-group, .editor-head .checkbox {
+ margin-bottom: 0;
+}
+
+.paste-main #tab-paste-edit, .paste-main #tab-paste-view {
+ padding-top: 10px;
+}
+
+.paste-description-content {
+ margin-top: 10px;
+}
+
+.paste-main .paste-tabs {
+ margin-top: 10px;
+}
\ No newline at end of file
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/images/favicon.ico b/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/images/favicon.ico
new file mode 100644
index 0000000..e59f188
Binary files /dev/null and b/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/images/favicon.ico differ
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/js/copypaste.js b/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/js/copypaste.js
new file mode 100644
index 0000000..977dfde
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/public/js/copypaste.js
@@ -0,0 +1,9 @@
+$(function () {
+ var $qr_link = $('#paste-qr-code');
+ $qr_link.popover({
+ content: ' ',
+ placement: 'bottom',
+ trigger: 'focus',
+ html: true
+ });
+});
\ No newline at end of file
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Copypaste/new.html.twig b/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Copypaste/new.html.twig
new file mode 100644
index 0000000..69f87c5
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Copypaste/new.html.twig
@@ -0,0 +1,6 @@
+{% extends '::base.html.twig' %}
+
+{% block content %}
+ {# This form recieves form_create object from current context #}
+ {% include 'SkobkinCopyPasteBundle:Form:form_paste_create.html.twig' %}
+{% endblock %}
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Copypaste/show.html.twig b/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Copypaste/show.html.twig
new file mode 100644
index 0000000..dff9048
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Copypaste/show.html.twig
@@ -0,0 +1,76 @@
+{% extends '::base.html.twig' %}
+
+{% block content %}
+
+
+
+ {% if paste.author %}
+ {{ paste.author }}
+ {% else %}
+ anonymous
+ {% endif %}
+
+
{{ paste.language }}
+
{{ paste.datePublished | date('Y.m.d H:i') }}
+
+ {% if paste.dateExpire %}
+ {{ paste.dateExpire | date('Y.m.d H:i') }}
+ {% endif %}
+
+
+
+
+ {% if paste.description %}
+
+
+
+ {{ paste.description | nl2br }}
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+ {{ highlighted_text | raw }}
+
+
+
+ {# This form recieves form_create object from current context #}
+ {% include 'SkobkinCopyPasteBundle:Form:form_paste_create.html.twig' %}
+
+
+
+
+
+
+{% endblock %}
diff --git a/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Form/form_paste_create.html.twig b/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Form/form_paste_create.html.twig
new file mode 100644
index 0000000..25fc7c2
--- /dev/null
+++ b/src/Skobkin/Bundle/CopyPasteBundle/Resources/views/Form/form_paste_create.html.twig
@@ -0,0 +1,42 @@
+
\ No newline at end of file
diff --git a/web/apple-touch-icon.png b/web/apple-touch-icon.png
deleted file mode 100644
index 11f17e6..0000000
Binary files a/web/apple-touch-icon.png and /dev/null differ