From 9921a789e5c67b2a1c724411ec741694052a3934 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Wed, 15 Oct 2014 17:23:12 +0200 Subject: [PATCH 01/40] Implemented search by tags with these operators: AND (&), OR (|) Fixes #30 --- .../Controller/TagController.php | 100 +++++++++++++++--- .../Resources/views/Event/index.html.twig | 35 ++++-- 2 files changed, 116 insertions(+), 19 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php index 1d0c43b..56974f5 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php @@ -25,6 +25,7 @@ use Jsvrcek\ICS\Utility\Formatter; use Jsvrcek\ICS\CalendarStream; use Jsvrcek\ICS\CalendarExport; use Symfony\Component\Validator\Constraints\DateTime; +use Doctrine\ORM\Query\ResultSetMappingBuilder; /** * Tag controller. @@ -47,26 +48,98 @@ class TagController extends Controller /** @var EntityRepository $repo */ $repo = $em->getRepository('CalciferBundle:Tag'); + $tags = []; + $operator = 'or'; + if (strpos($slug,'|') !== false) { + $slugs = explode('|',$slug); + foreach($slugs as $item) { + /** @var Tag $tag */ + $tag = $repo->findOneBy(['slug' => $item]); - /** @var Tag $location */ - $tag = $repo->findOneBy(['slug' => $slug]); + if ($tag instanceof Tag) { + $tags[] = $tag; + } + } + } else if (strpos($slug,'&') !== false) { + $slugs = explode('&',$slug); + $operator = 'and'; + foreach($slugs as $item) { + /** @var Tag $tag */ + $tag = $repo->findOneBy(['slug' => $item]); - if (!$tag) { + if ($tag instanceof Tag) { + $tags[] = $tag; + } + } + } else { + /** @var Tag $tag */ + $tag = $repo->findOneBy(['slug' => $slug]); + + if ($tag instanceof Tag) { + $tags[] = $tag; + } + } + + if (count($tags) == 0) { throw $this->createNotFoundException('Unable to find tag entity.'); } $now = new \DateTime(); $now->setTime(0, 0, 0); - /** @var QueryBuilder $qb */ - $qb = $em->createQueryBuilder(); - $qb->select(array('e')) - ->from('CalciferBundle:Event', 'e') - ->join('e.tags', 't', 'WITH', $qb->expr()->in('t.id', $tag->id)) - ->where('e.startdate >= :startdate') - ->orderBy('e.startdate') - ->setParameter('startdate', $now); - $entities = $qb->getQuery()->execute(); + $entities = null; + if ($operator == 'and') { + $sql = << array[@tags@] +) +AND e.startdate >= :startdate +ORDER BY e.startdate +EOF; + $tag_ids = array_reduce($tags,function($carry,$item){ + if (strlen($carry) == 0) { + return $item->id; + } else { + return $carry . ',' . $item->id; + } + }); + + $sql = str_replace('@tags@',$tag_ids,$sql); + + $rsm = new ResultSetMappingBuilder($em); + $rsm->addRootEntityFromClassMetadata('CalciferBundle:Event','e'); + + $query = $em->createNativeQuery($sql,$rsm); + + $query->setParameter('startdate',$now); + + $entities = $query->getResult(); + + } else { + /** @var QueryBuilder $qb */ + $qb = $em->createQueryBuilder(); + $qb->select(array('e')) + ->from('CalciferBundle:Event', 'e') + ->where('e.startdate >= :startdate') + ->orderBy('e.startdate') + ->setParameter('startdate', $now); + + $qb->join('e.tags', 't', 'WITH', $qb->expr()->in('t.id', array_reduce($tags,function($carry,$item){ + if (strlen($carry) == 0) { + return $item->id; + } else { + return $carry . ',' . $item->id; + } + }))); + $entities = $qb->getQuery()->execute(); + } if ($format == 'ics') { $calendar = new Calendar(); @@ -110,7 +183,8 @@ class TagController extends Controller } else { return array( 'entities' => $entities, - 'tag' => $tag, + 'tags' => $tags, + 'operator' => $operator, ); } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig index bc86b24..457520b 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig @@ -23,7 +23,22 @@

Termine - {% if tag|default(false) %} für Tag „{{ tag.name }}“{% endif %} + {% if tags|default(false) %} + {% if tags|length == 1 %} + für Tag {{ tags[0].name }} + {% elseif(tags|length == 2) %} + für die Tags {{ tags[0].name }} {% if operator == 'or' %}oder{% else %}und{% endif %} {{ tags[1].name }} + {% else %} + für die Tags + {% for tag in tags %} + {% if not loop.last %} + {{ tag.name }}{% if loop.index < (tags|length - 1) %},{% endif %} + {% else %} + {% if operator == 'or' %}oder{% else %}und{% endif %} {{ tag.name }} + {% endif %} + {% endfor %} + {% endif %} + {% endif %} {% if location|default(false) %} für Ort „{{ location.name }}“ {% endif %}

{% if tag|default(false) %} @@ -68,10 +83,18 @@
-
- {% for entity in entities %} - {{ include('CalciferBundle:Event:event_box.html.twig',{'truncate_summary':true}) }} - {% endfor %} -
+ {% if entities|length > 0 %} +
+ {% for entity in entities %} + {{ include('CalciferBundle:Event:event_box.html.twig',{'truncate_summary':true}) }} + {% endfor %} +
+ {% else %} +
+
+

Es konnten keine Termine gefunden werden.

+
+
+ {% endif %} {% endblock %} From 6a37d7709293a102a90d2f97db1923c986b6193f Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 15 Nov 2014 16:30:38 +0100 Subject: [PATCH 02/40] Update dependencies. --- composer.lock | 247 +++++++++++++++++++++----------------------------- 1 file changed, 101 insertions(+), 146 deletions(-) diff --git a/composer.lock b/composer.lock index ba7ddf7..be254b4 100644 --- a/composer.lock +++ b/composer.lock @@ -198,7 +198,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", + "homepage": "https://github.com/schmittjoh", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -274,7 +274,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", + "homepage": "https://github.com/schmittjoh", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -291,16 +291,16 @@ }, { "name": "doctrine/dbal", - "version": "v2.4.2", + "version": "v2.4.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "fec965d330c958e175c39e61c3f6751955af32d0" + "reference": "0368bc031976126e5d36d37d2c56155092b6575b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/fec965d330c958e175c39e61c3f6751955af32d0", - "reference": "fec965d330c958e175c39e61c3f6751955af32d0", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/0368bc031976126e5d36d37d2c56155092b6575b", + "reference": "0368bc031976126e5d36d37d2c56155092b6575b", "shasum": "" }, "require": { @@ -312,7 +312,7 @@ "symfony/console": "~2.0" }, "suggest": { - "symfony/console": "Allows use of the command line interface" + "symfony/console": "For helpful console commands such as SQL execution and import of files." }, "type": "library", "autoload": { @@ -325,17 +325,6 @@ "MIT" ], "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/", - "role": "Creator" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -343,6 +332,14 @@ { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" } ], "description": "Database Abstraction Layer", @@ -353,7 +350,7 @@ "persistence", "queryobject" ], - "time": "2014-01-01 16:43:57" + "time": "2014-10-16 11:56:49" }, { "name": "doctrine/doctrine-bundle", @@ -536,7 +533,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", + "homepage": "https://github.com/schmittjoh", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -590,7 +587,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", + "homepage": "https://github.com/schmittjoh", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -608,12 +605,12 @@ "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021" + "reference": "f4fe9d9cc21a711d89d91d29c4a4e7945289cdd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021", - "reference": "1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/f4fe9d9cc21a711d89d91d29c4a4e7945289cdd0", + "reference": "f4fe9d9cc21a711d89d91d29c4a4e7945289cdd0", "shasum": "" }, "require": { @@ -658,20 +655,20 @@ "database", "migrations" ], - "time": "2014-08-18 18:03:07" + "time": "2014-10-30 14:49:25" }, { "name": "doctrine/orm", - "version": "v2.4.5", + "version": "v2.4.6", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "c0d3cdbdfbf873871167050ab077e49b1ad02ab0" + "reference": "bebacf79d8d4dae9168f0f9bc6811e6c2cb6a4d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/c0d3cdbdfbf873871167050ab077e49b1ad02ab0", - "reference": "c0d3cdbdfbf873871167050ab077e49b1ad02ab0", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/bebacf79d8d4dae9168f0f9bc6811e6c2cb6a4d9", + "reference": "bebacf79d8d4dae9168f0f9bc6811e6c2cb6a4d9", "shasum": "" }, "require": { @@ -731,7 +728,7 @@ "database", "orm" ], - "time": "2014-09-22 21:58:51" + "time": "2014-10-06 13:22:50" }, { "name": "enko/ics", @@ -1053,16 +1050,16 @@ }, { "name": "kriswallsmith/assetic", - "version": "v1.1.2", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/kriswallsmith/assetic.git", - "reference": "735cffd3982c6e8cdebe292d5db39d077f65890f" + "reference": "df991c124a2212371443b586a1be767500036dee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/735cffd3982c6e8cdebe292d5db39d077f65890f", - "reference": "735cffd3982c6e8cdebe292d5db39d077f65890f", + "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/df991c124a2212371443b586a1be767500036dee", + "reference": "df991c124a2212371443b586a1be767500036dee", "shasum": "" }, "require": { @@ -1077,7 +1074,9 @@ "leafo/scssphp": "*", "leafo/scssphp-compass": "*", "mrclay/minify": "*", - "phpunit/phpunit": "~3.7", + "patchwork/jsqueeze": "~1.0", + "phpunit/phpunit": "~4", + "psr/log": "~1.0", "ptachoire/cssembed": "*", "twig/twig": "~1.6" }, @@ -1085,13 +1084,14 @@ "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin", + "patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor", "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris", "twig/twig": "Assetic provides the integration with the Twig templating engine" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -1120,7 +1120,7 @@ "compression", "minification" ], - "time": "2013-07-19 00:03:27" + "time": "2014-10-14 14:45:32" }, { "name": "michelf/php-markdown", @@ -1285,17 +1285,17 @@ }, { "name": "sensio/distribution-bundle", - "version": "v3.0.6", + "version": "v3.0.8", "target-dir": "Sensio/Bundle/DistributionBundle", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", - "reference": "e20461e4f8e1afd68f36cf90bdccc06f7aa6a6c2" + "reference": "bc5e96bb4faf6bee7121085951d11b89488952f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/e20461e4f8e1afd68f36cf90bdccc06f7aa6a6c2", - "reference": "e20461e4f8e1afd68f36cf90bdccc06f7aa6a6c2", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/bc5e96bb4faf6bee7121085951d11b89488952f5", + "reference": "bc5e96bb4faf6bee7121085951d11b89488952f5", "shasum": "" }, "require": { @@ -1303,7 +1303,7 @@ "sensiolabs/security-checker": "~2.0", "symfony/class-loader": "~2.2", "symfony/form": "~2.2", - "symfony/framework-bundle": "~2.4", + "symfony/framework-bundle": "~2.3", "symfony/process": "~2.2", "symfony/validator": "~2.2", "symfony/yaml": "~2.2" @@ -1334,21 +1334,21 @@ "configuration", "distribution" ], - "time": "2014-09-24 14:47:46" + "time": "2014-11-03 21:16:34" }, { "name": "sensio/framework-extra-bundle", - "version": "v3.0.2", + "version": "v3.0.3", "target-dir": "Sensio/Bundle/FrameworkExtraBundle", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", - "reference": "9b22aaee517e80aad3238ea0328458b6f964066f" + "reference": "b829a8097a41ccbd7d35683b1750043b23d682f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/9b22aaee517e80aad3238ea0328458b6f964066f", - "reference": "9b22aaee517e80aad3238ea0328458b6f964066f", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/b829a8097a41ccbd7d35683b1750043b23d682f5", + "reference": "b829a8097a41ccbd7d35683b1750043b23d682f5", "shasum": "" }, "require": { @@ -1389,7 +1389,7 @@ "annotations", "controllers" ], - "time": "2014-09-02 07:11:30" + "time": "2014-11-10 14:50:31" }, { "name": "sensiolabs/security-checker", @@ -1438,20 +1438,20 @@ }, { "name": "swiftmailer/swiftmailer", - "version": "v5.2.2", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "e02f71a35436af4bd58a1bd90116089e632e29e1" + "reference": "b86b927dfefdb56ab0b22d1350033d9a38e9f205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/e02f71a35436af4bd58a1bd90116089e632e29e1", - "reference": "e02f71a35436af4bd58a1bd90116089e632e29e1", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/b86b927dfefdb56ab0b22d1350033d9a38e9f205", + "reference": "b86b927dfefdb56ab0b22d1350033d9a38e9f205", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.3.3" }, "require-dev": { "mockery/mockery": "~0.9.1" @@ -1459,7 +1459,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.2-dev" + "dev-master": "5.3-dev" } }, "autoload": { @@ -1486,49 +1486,50 @@ "mail", "mailer" ], - "time": "2014-09-20 07:17:36" + "time": "2014-10-04 05:53:18" }, { "name": "symfony/assetic-bundle", - "version": "v2.3.0", - "target-dir": "Symfony/Bundle/AsseticBundle", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/AsseticBundle.git", - "reference": "146dd3cb46b302bd471560471c6aaa930483dac1" + "reference": "90ea7fb66d6d5245fd4afc16e4c8070214254fec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/AsseticBundle/zipball/146dd3cb46b302bd471560471c6aaa930483dac1", - "reference": "146dd3cb46b302bd471560471c6aaa930483dac1", + "url": "https://api.github.com/repos/symfony/AsseticBundle/zipball/90ea7fb66d6d5245fd4afc16e4c8070214254fec", + "reference": "90ea7fb66d6d5245fd4afc16e4c8070214254fec", "shasum": "" }, "require": { - "kriswallsmith/assetic": "~1.1", + "kriswallsmith/assetic": "~1.2", "php": ">=5.3.0", - "symfony/framework-bundle": "~2.1" - }, - "require-dev": { - "symfony/class-loader": "~2.1", "symfony/console": "~2.1", - "symfony/css-selector": "~2.1", - "symfony/dom-crawler": "~2.1", - "symfony/form": "~2.1", - "symfony/twig-bundle": "~2.1", + "symfony/framework-bundle": "~2.1", "symfony/yaml": "~2.1" }, - "suggest": { + "require-dev": { + "kriswallsmith/spork": "~0.2", + "patchwork/jsqueeze": "~1.0", + "symfony/class-loader": "~2.1", + "symfony/css-selector": "~2.1", + "symfony/dom-crawler": "~2.1", "symfony/twig-bundle": "~2.1" }, + "suggest": { + "kriswallsmith/spork": "to be able to dump assets in parallel", + "symfony/twig-bundle": "to use the Twig integration" + }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "2.5-dev" } }, "autoload": { - "psr-0": { - "Symfony\\Bundle\\AsseticBundle": "" + "psr-4": { + "Symfony\\Bundle\\AsseticBundle\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1549,56 +1550,7 @@ "compression", "minification" ], - "time": "2013-05-16 05:32:23" - }, - { - "name": "symfony/icu", - "version": "v1.2.2", - "target-dir": "Symfony/Component/Icu", - "source": { - "type": "git", - "url": "https://github.com/symfony/Icu.git", - "reference": "d4d85d6055b87f394d941b45ddd3a9173e1e3d2a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Icu/zipball/d4d85d6055b87f394d941b45ddd3a9173e1e3d2a", - "reference": "d4d85d6055b87f394d941b45ddd3a9173e1e3d2a", - "shasum": "" - }, - "require": { - "ext-intl": "*", - "lib-icu": ">=4.4", - "php": ">=5.3.3", - "symfony/intl": "~2.3" - }, - "type": "library", - "autoload": { - "psr-0": { - "Symfony\\Component\\Icu\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Contains an excerpt of the ICU data and classes to load it.", - "homepage": "http://symfony.com", - "keywords": [ - "icu", - "intl" - ], - "time": "2014-07-25 09:58:17" + "time": "2014-10-15 12:03:38" }, { "name": "symfony/monolog-bundle", @@ -1718,23 +1670,22 @@ }, { "name": "symfony/symfony", - "version": "v2.5.5", + "version": "v2.5.6", "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", - "reference": "2aef97bbc95d0c4ae63537cca81bd6d984427d81" + "reference": "1a1b1e528935f15dd76169f8b1dc3ef97f0d6210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/symfony/zipball/2aef97bbc95d0c4ae63537cca81bd6d984427d81", - "reference": "2aef97bbc95d0c4ae63537cca81bd6d984427d81", + "url": "https://api.github.com/repos/symfony/symfony/zipball/1a1b1e528935f15dd76169f8b1dc3ef97f0d6210", + "reference": "1a1b1e528935f15dd76169f8b1dc3ef97f0d6210", "shasum": "" }, "require": { "doctrine/common": "~2.2", "php": ">=5.3.3", "psr/log": "~1.0", - "symfony/icu": "~1.0", "twig/twig": "~1.12" }, "replace": { @@ -1828,29 +1779,35 @@ "keywords": [ "framework" ], - "time": "2014-09-28 17:33:53" + "time": "2014-10-24 06:55:39" }, { "name": "twig/extensions", - "version": "v1.1.0", + "version": "v1.2.0", "source": { "type": "git", - "url": "https://github.com/fabpot/Twig-extensions.git", - "reference": "c0ab818595338dd5569369bfce2552d02cec5d50" + "url": "https://github.com/twigphp/Twig-extensions.git", + "reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Twig-extensions/zipball/c0ab818595338dd5569369bfce2552d02cec5d50", - "reference": "c0ab818595338dd5569369bfce2552d02cec5d50", + "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/8cf4b9fe04077bd54fc73f4fde83347040c3b8cd", + "reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd", "shasum": "" }, "require": { "twig/twig": "~1.12" }, + "require-dev": { + "symfony/translation": "~2.3" + }, + "suggest": { + "symfony/translation": "Allow the time_diff output to be translated" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1865,31 +1822,29 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "email": "fabien@symfony.com" } ], "description": "Common additional features for Twig that do not directly belong in core", - "homepage": "https://github.com/fabpot/Twig-extensions", + "homepage": "http://twig.sensiolabs.org/doc/extensions/index.html", "keywords": [ "i18n", "text" ], - "time": "2014-07-05 10:01:35" + "time": "2014-10-30 14:30:03" }, { "name": "twig/twig", - "version": "v1.16.0", + "version": "v1.16.2", "source": { "type": "git", - "url": "https://github.com/fabpot/Twig.git", - "reference": "8ce37115802e257a984a82d38254884085060024" + "url": "https://github.com/twigphp/Twig.git", + "reference": "42f758d9fe2146d1f0470604fc05ee43580873fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Twig/zipball/8ce37115802e257a984a82d38254884085060024", - "reference": "8ce37115802e257a984a82d38254884085060024", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/42f758d9fe2146d1f0470604fc05ee43580873fc", + "reference": "42f758d9fe2146d1f0470604fc05ee43580873fc", "shasum": "" }, "require": { @@ -1933,7 +1888,7 @@ "keywords": [ "templating" ], - "time": "2014-07-05 12:19:05" + "time": "2014-10-17 12:53:44" } ], "packages-dev": [ From 097469b3765dff8edae62a5b207bdbadab9e5ae2 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 15 Nov 2014 16:31:02 +0100 Subject: [PATCH 03/40] Add the default sqlite db to the ignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fa563fa..2a12fd9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /vendor/ /bin/ /composer.phar +app/calcifer.sqlite3 \ No newline at end of file From dbb74b06dca496c37fcc3770cac16e30beae6a5f Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 15 Nov 2014 21:30:49 +0100 Subject: [PATCH 04/40] Extracted some duplicate code into a common function. --- .../Controller/LocationController.php | 34 +++----------- .../Controller/TagController.php | 44 ++++++------------- .../Bundle/CalciferBundle/Entity/Event.php | 35 +++++++++++++++ 3 files changed, 53 insertions(+), 60 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php index fc07a8c..64b174a 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php @@ -17,14 +17,9 @@ use Hackspace\Bundle\CalciferBundle\Entity\Event; use Hackspace\Bundle\CalciferBundle\Form\EventType; use Symfony\Component\HttpFoundation\Response; use Jsvrcek\ICS\Model\Calendar; -use Jsvrcek\ICS\Model\CalendarEvent; -use Jsvrcek\ICS\Model\Relationship\Attendee; -use Jsvrcek\ICS\Model\Relationship\Organizer; - use Jsvrcek\ICS\Utility\Formatter; use Jsvrcek\ICS\CalendarStream; use Jsvrcek\ICS\CalendarExport; -use Jsvrcek\ICS\Model\Description\Geo; /** * Location controller. @@ -77,27 +72,7 @@ class LocationController extends Controller foreach ($entities as $entity) { /** @var Event $entity */ - $event = new CalendarEvent(); - $event->setStart($entity->startdate); - if ($entity->enddate instanceof \DateTime) - $event->setEnd($entity->enddate); - $event->setSummary($entity->summary); - $event->setUrl($entity->url); - if ($entity->location instanceof Location) { - $location = new \Jsvrcek\ICS\Model\Description\Location(); - $location->setName($entity->location->name); - $event->setLocations([$location]); - if (\is_float($entity->location->lon) && \is_float($entity->location->lat)) { - $geo = new Geo(); - $geo->setLatitude($entity->location->lat); - $geo->setLongitude($entity->location->lon); - $event->setGeo($geo); - } - } - $event->setDescription($entity->description); - $location = new \Jsvrcek\ICS\Model\Description\Location(); - $location->setName($entity->getLocation()->name); - $event->setLocations([$location]); + $event = $entity->ConvertToCalendarEvent(); $calendar->addEvent($event); } @@ -152,7 +127,8 @@ class LocationController extends Controller * @Route("/{slug}/bearbeiten", name="location_update") * @Method("POST") */ - public function updateAction(Request $request, $slug) { + public function updateAction(Request $request, $slug) + { /** @var EntityManager $em */ $em = $this->getDoctrine()->getManager(); @@ -168,7 +144,7 @@ class LocationController extends Controller if ($location->name != $request->get('name')) { $location->name = $request->get('name'); - $location->slug = $location->generateSlug($location->name,$em); + $location->slug = $location->generateSlug($location->name, $em); } $location->streetaddress = $request->get('streetaddress'); $location->streetnumber = $request->get('streetnumber'); @@ -177,7 +153,7 @@ class LocationController extends Controller $location->description = $request->get('description'); $latlon = $request->get('geocords'); - $latlon = explode(',',$latlon); + $latlon = explode(',', $latlon); if (count($latlon) == 2) { $location->lat = $latlon[0]; $location->lon = $latlon[1]; diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php index 56974f5..e905075 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php @@ -50,9 +50,9 @@ class TagController extends Controller $repo = $em->getRepository('CalciferBundle:Tag'); $tags = []; $operator = 'or'; - if (strpos($slug,'|') !== false) { - $slugs = explode('|',$slug); - foreach($slugs as $item) { + if (strpos($slug, '|') !== false) { + $slugs = explode('|', $slug); + foreach ($slugs as $item) { /** @var Tag $tag */ $tag = $repo->findOneBy(['slug' => $item]); @@ -60,10 +60,10 @@ class TagController extends Controller $tags[] = $tag; } } - } else if (strpos($slug,'&') !== false) { - $slugs = explode('&',$slug); + } else if (strpos($slug, '&') !== false) { + $slugs = explode('&', $slug); $operator = 'and'; - foreach($slugs as $item) { + foreach ($slugs as $item) { /** @var Tag $tag */ $tag = $repo->findOneBy(['slug' => $item]); @@ -103,7 +103,7 @@ WHERE tags @> array[@tags@] AND e.startdate >= :startdate ORDER BY e.startdate EOF; - $tag_ids = array_reduce($tags,function($carry,$item){ + $tag_ids = array_reduce($tags, function ($carry, $item) { if (strlen($carry) == 0) { return $item->id; } else { @@ -111,14 +111,14 @@ EOF; } }); - $sql = str_replace('@tags@',$tag_ids,$sql); + $sql = str_replace('@tags@', $tag_ids, $sql); $rsm = new ResultSetMappingBuilder($em); - $rsm->addRootEntityFromClassMetadata('CalciferBundle:Event','e'); + $rsm->addRootEntityFromClassMetadata('CalciferBundle:Event', 'e'); - $query = $em->createNativeQuery($sql,$rsm); + $query = $em->createNativeQuery($sql, $rsm); - $query->setParameter('startdate',$now); + $query->setParameter('startdate', $now); $entities = $query->getResult(); @@ -131,7 +131,7 @@ EOF; ->orderBy('e.startdate') ->setParameter('startdate', $now); - $qb->join('e.tags', 't', 'WITH', $qb->expr()->in('t.id', array_reduce($tags,function($carry,$item){ + $qb->join('e.tags', 't', 'WITH', $qb->expr()->in('t.id', array_reduce($tags, function ($carry, $item) { if (strlen($carry) == 0) { return $item->id; } else { @@ -148,25 +148,7 @@ EOF; foreach ($entities as $entity) { /** @var Event $entity */ - $event = new CalendarEvent(); - $event->setStart($entity->startdate); - if ($entity->enddate instanceof \DateTime) - $event->setEnd($entity->enddate); - $event->setSummary($entity->summary); - $event->setDescription($entity->description); - $event->setUrl($entity->url); - $event->setUid($entity->slug); - if ($entity->location instanceof Location) { - $location = new \Jsvrcek\ICS\Model\Description\Location(); - $location->setName($entity->location->name); - $event->setLocations([$location]); - if (\is_float($entity->location->lon) && \is_float($entity->location->lat)) { - $geo = new Geo(); - $geo->setLatitude($entity->location->lat); - $geo->setLongitude($entity->location->lon); - $event->setGeo($geo); - } - } + $event = $entity->ConvertToCalendarEvent(); $calendar->addEvent($event); } diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php index 68104d4..eb23903 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php @@ -2,8 +2,20 @@ namespace Hackspace\Bundle\CalciferBundle\Entity; + + use Doctrine\ORM\Mapping as ORM; +use Jsvrcek\ICS\Model\Description\Location; use Symfony\Component\Validator\Constraints\DateTime; +use Jsvrcek\ICS\Model\Calendar; +use Jsvrcek\ICS\Model\CalendarEvent; +use Jsvrcek\ICS\Model\Relationship\Attendee; +use Jsvrcek\ICS\Model\Relationship\Organizer; + +use Jsvrcek\ICS\Utility\Formatter; +use Jsvrcek\ICS\CalendarStream; +use Jsvrcek\ICS\CalendarExport; +use Jsvrcek\ICS\Model\Description\Geo; /** * Event @@ -129,4 +141,27 @@ class Event extends BaseEntity } return $retval; } + + + public function ConvertToCalendarEvent() { + $event = new CalendarEvent(); + $event->setStart($this->startdate); + if ($this->enddate instanceof \DateTime) + $event->setEnd($this->enddate); + $event->setSummary($this->summary); + $event->setUrl($this->url); + if ($this->location instanceof Location) { + $location = new Location(); + $location->setName($this->location->name); + $event->setLocations([$location]); + if (\is_float($this->location->lon) && \is_float($this->location->lat)) { + $geo = new Geo(); + $geo->setLatitude($this->location->lat); + $geo->setLongitude($this->location->lon); + $event->setGeo($geo); + } + } + $event->setDescription($this->description); + return $event; + } } From 2f1d60f3cc80442131ea61d6d31ce62bb830ce72 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 15 Nov 2014 21:33:58 +0100 Subject: [PATCH 05/40] Add sabre.io to the dependencies. Ticket #31 --- composer.json | 3 +- composer.lock | 235 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 236 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 12f7112..faa8d52 100755 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "doctrine/migrations": "dev-master", "doctrine/doctrine-migrations-bundle": "dev-master", "jbroadway/urlify" : "~1.0", - "enko/relativedateparser" : "v0.3" + "enko/relativedateparser" : "v0.3", + "sabre/dav" : "~2.0" }, "require-dev": { "sensio/generator-bundle": "~2.3" diff --git a/composer.lock b/composer.lock index be254b4..6d814aa 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "76317aae6b4148c72d1d1afc039502d9", + "hash": "c0dd295d10e8821f679de1dc090aa14e", "packages": [ { "name": "doctrine/annotations", @@ -1283,6 +1283,239 @@ ], "time": "2012-12-21 11:40:51" }, + { + "name": "sabre/dav", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-dav.git", + "reference": "e390d39ebfc701543459370e89a16d2d71910bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/e390d39ebfc701543459370e89a16d2d71910bda", + "reference": "e390d39ebfc701543459370e89a16d2d71910bda", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-dom": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "php": ">=5.4.1", + "sabre/event": "~1.0.0", + "sabre/http": "~2.0.2", + "sabre/vobject": "~3.3.0" + }, + "require-dev": { + "evert/phpdoc-md": "~0.0.7", + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-curl": "*", + "ext-pdo": "*" + }, + "bin": [ + "bin/sabredav", + "bin/naturalselection" + ], + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\DAV\\": "lib/DAV/", + "Sabre\\DAVACL\\": "lib/DAVACL/", + "Sabre\\CalDAV\\": "lib/CalDAV/", + "Sabre\\CardDAV\\": "lib/CardDAV/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "WebDAV Framework for PHP", + "homepage": "http://code.google.com/p/sabredav/", + "keywords": [ + "CalDAV", + "CardDAV", + "WebDAV", + "framework", + "iCalendar" + ], + "time": "2014-10-14 16:14:28" + }, + { + "name": "sabre/event", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-event.git", + "reference": "5ee3adf5441c2fe53b8ceacff6db81e621ee884c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-event/zipball/5ee3adf5441c2fe53b8ceacff6db81e621ee884c", + "reference": "5ee3adf5441c2fe53b8ceacff6db81e621ee884c", + "shasum": "" + }, + "require": { + "php": ">=5.4.1" + }, + "type": "library", + "autoload": { + "psr-0": { + "Sabre\\Event": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "evert@rooftopsolutions.nl", + "homepage": "http://www.rooftopsolutions.nl/", + "role": "Developer" + } + ], + "description": "The sabre/event library provides utilities for lightweight event-based programming", + "homepage": "http://sabre.io/event", + "keywords": [ + "EventEmitter", + "events" + ], + "time": "2014-06-12 16:34:49" + }, + { + "name": "sabre/http", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-http.git", + "reference": "c4c24f547a5509c6c661b11ecf4ff524d2bf6a44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-http/zipball/c4c24f547a5509c6c661b11ecf4ff524d2bf6a44", + "reference": "c4c24f547a5509c6c661b11ecf4ff524d2bf6a44", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.4", + "sabre/event": ">=1.0.0,<3.0.0" + }, + "require-dev": { + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "~1.5.3" + }, + "suggest": { + "ext-curl": " to make http requests with the Client class" + }, + "type": "library", + "autoload": { + "psr-0": { + "Sabre\\HTTP": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "evert@rooftopsolutions.nl", + "homepage": "http://www.rooftopsolutions.nl/", + "role": "Developer" + } + ], + "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", + "homepage": "https://github.com/fruux/sabre-http", + "keywords": [ + "http" + ], + "time": "2014-07-14 18:13:13" + }, + { + "name": "sabre/vobject", + "version": "3.3.3", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-vobject.git", + "reference": "de508f160e811c09b5e651909eb20b9e058a043c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/de508f160e811c09b5e651909eb20b9e058a043c", + "reference": "de508f160e811c09b5e651909eb20b9e058a043c", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "*" + }, + "bin": [ + "bin/vobject", + "bin/generate_vcards" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\VObject\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Dominik Tobschall", + "email": "dominik@fruux.com", + "homepage": "http://tobschall.de/", + "role": "Developer" + } + ], + "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", + "homepage": "http://sabre.io/vobject/", + "keywords": [ + "VObject", + "iCalendar", + "jCal", + "jCard", + "vCard" + ], + "time": "2014-10-09 15:59:25" + }, { "name": "sensio/distribution-bundle", "version": "v3.0.8", From 539616f7b7c6d066379bfd4ad6cd77e81d39230e Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 15 Nov 2014 21:34:38 +0100 Subject: [PATCH 06/40] Add a principal and a caldav backend for sabre to work with. Ticket #31 --- .../libs/CalciferCaldavBackend.php | 305 ++++++++++++++++++ .../libs/CalciferPrincipalBackend.php | 158 +++++++++ 2 files changed, 463 insertions(+) create mode 100644 src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php create mode 100644 src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php diff --git a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php new file mode 100644 index 0000000..cf5f95e --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php @@ -0,0 +1,305 @@ +controller = $controller; + } + + /** + * Returns a list of calendars for a principal. + * + * Every project is an array with the following keys: + * * id, a unique id that will be used by other functions to modify the + * calendar. This can be the same as the uri or a database key. + * * uri, which the basename of the uri with which the calendar is + * accessed. + * * principaluri. The owner of the calendar. Almost always the same as + * principalUri passed to this method. + * + * Furthermore it can contain webdav properties in clark notation. A very + * common one is '{DAV:}displayname'. + * + * Many clients also require: + * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set + * For this property, you can just return an instance of + * Sabre\CalDAV\Property\SupportedCalendarComponentSet. + * + * @param string $principalUri + * @return array + */ + public function getCalendarsForUser($principalUri) + { + return [[ + 'id' => 1, + 'uri' => 'calendar', + 'principaluri' => '/caldav/calcifer', + ]]; + } + + /** + * Creates a new calendar for a principal. + * + * If the creation was a success, an id must be returned that can be used to reference + * this calendar in other methods, such as updateCalendar. + * + * @param string $principalUri + * @param string $calendarUri + * @param array $properties + * @return void + */ + public function createCalendar($principalUri, $calendarUri, array $properties) + { + throw new \Exception('Not implemented'); + } + + /** + * Delete a calendar and all it's objects + * + * @param mixed $calendarId + * @return void + */ + public function deleteCalendar($calendarId) + { + throw new \Exception('Not implemented'); + } + + private function FormatCalendarEvent(CalendarEvent $event) + { + $stream = new CalendarStream(); + $formatter = new Formatter(); + $stream->addItem('BEGIN:VEVENT') + ->addItem('UID:' . $event->getUid()) + ->addItem('DTSTART:' . $formatter->getFormattedUTCDateTime($event->getStart())) + ->addItem('DTEND:' . $formatter->getFormattedUTCDateTime($event->getEnd())) + ->addItem('SUMMARY:' . $event->getSummary()) + ->addItem('DESCRIPTION:' . $event->getDescription()); + + if ($event->getClass()) + $stream->addItem('CLASS:' . $event->getClass()); + + /* @var $location Location */ + foreach ($event->getLocations() as $location) { + $stream + ->addItem('LOCATION' . $location->getUri() . $location->getLanguage() . ':' . $location->getName()); + } + + if ($event->getGeo()) + $stream->addItem('GEO:' . $event->getGeo()->getLatitude() . ';' . $event->getGeo()->getLongitude()); + + if ($event->getUrl()) + $stream->addItem('URL:' . $event->getUrl()); + + if ($event->getCreated()) + $stream->addItem('CREATED:' . $formatter->getFormattedUTCDateTime($event->getCreated())); + + if ($event->getLastModified()) + $stream->addItem('LAST-MODIFIED:' . $formatter->getFormattedUTCDateTime($event->getLastModified())); + + foreach ($event->getAttendees() as $attendee) { + $stream->addItem($attendee->__toString()); + } + + if ($event->getOrganizer()) + $stream->addItem($event->getOrganizer()->__toString()); + + $stream->addItem('END:VEVENT'); + + return $stream->getStream(); + } + + private function formatEvent(Event $event) + { + /** @var CalendarEvent $calendar_event */ + $calendar_event = $event->ConvertToCalendarEvent(); + $calendar_data = $this->FormatCalendarEvent($calendar_event); + + $event_data = [ + 'id' => $event->id, + 'uri' => $event->slug, + 'lastmodified' => $event->startdate, + 'etag' => '"' . sha1($calendar_data) . '"', + 'calendarid' => 1, + 'calendardata' => $calendar_data, + 'size' => strlen($calendar_data), + 'component' => 'VEVENT', + ]; + return $event_data; + } + + /** + * Returns all calendar objects within a calendar. + * + * Every item contains an array with the following keys: + * * id - unique identifier which will be used for subsequent updates + * * calendardata - The iCalendar-compatible calendar data + * * uri - a unique key which will be used to construct the uri. This can + * be any arbitrary string, but making sure it ends with '.ics' is a + * good idea. This is only the basename, or filename, not the full + * path. + * * lastmodified - a timestamp of the last modification time + * * etag - An arbitrary string, surrounded by double-quotes. (e.g.: + * '"abcdef"') + * * calendarid - The calendarid as it was passed to this function. + * * size - The size of the calendar objects, in bytes. + * * component - optional, a string containing the type of object, such + * as 'vevent' or 'vtodo'. If specified, this will be used to populate + * the Content-Type header. + * + * Note that the etag is optional, but it's highly encouraged to return for + * speed reasons. + * + * The calendardata is also optional. If it's not returned + * 'getCalendarObject' will be called later, which *is* expected to return + * calendardata. + * + * If neither etag or size are specified, the calendardata will be + * used/fetched to determine these numbers. If both are specified the + * amount of times this is needed is reduced by a great degree. + * + * @param mixed $calendarId + * @return array + */ + public function getCalendarObjects($calendarId) + { + /** @var EntityManager $em */ + $em = $this->controller->getDoctrine()->getManager(); + + $now = new \DateTime(); + $now->setTime(0, 0, 0); + /** @var QueryBuilder $qb */ + $qb = $em->createQueryBuilder(); + $qb->select(array('e')) + ->from('CalciferBundle:Event', 'e') + ->where('e.startdate >= :startdate') + ->orderBy('e.startdate') + ->setParameter('startdate', $now); + $entities = $qb->getQuery()->execute(); + + if (count($entities) > 0) { + $events = []; + foreach ($entities as $event) { + /** @var Event $event */ + $events[] = $this->formatEvent($event); + } + return $events; + } + } + + /** + * Returns information from a single calendar object, based on it's object + * uri. + * + * The object uri is only the basename, or filename and not a full path. + * + * The returned array must have the same keys as getCalendarObjects. The + * 'calendardata' object is required here though, while it's not required + * for getCalendarObjects. + * + * This method must return null if the object did not exist. + * + * @param mixed $calendarId + * @param string $objectUri + * @return array|null + */ + public function getCalendarObject($calendarId, $objectUri) + { + /** @var EntityManager $em */ + $em = $this->controller->getDoctrine()->getManager(); + + /** @var EntityRepository $repo */ + $repo = $em->getRepository('CalciferBundle:Event'); + + /** @var Event $entity */ + $event = $repo->findOneBy(['slug' => $objectUri]); + + if (!($event instanceof Event)) { + throw $this->controller->createNotFoundException('Unable to find Event entity.'); + } + + return $this->formatEvent($event); + } + + /** + * Creates a new calendar object. + * + * The object uri is only the basename, or filename and not a full path. + * + * It is possible return an etag from this function, which will be used in + * the response to this PUT request. Note that the ETag must be surrounded + * by double-quotes. + * + * However, you should only really return this ETag if you don't mangle the + * calendar-data. If the result of a subsequent GET to this object is not + * the exact same as this request body, you should omit the ETag. + * + * @param mixed $calendarId + * @param string $objectUri + * @param string $calendarData + * @return string|null + */ + public function createCalendarObject($calendarId, $objectUri, $calendarData) + { + // TODO: Implement createCalendarObject() method. + } + + /** + * Updates an existing calendarobject, based on it's uri. + * + * The object uri is only the basename, or filename and not a full path. + * + * It is possible return an etag from this function, which will be used in + * the response to this PUT request. Note that the ETag must be surrounded + * by double-quotes. + * + * However, you should only really return this ETag if you don't mangle the + * calendar-data. If the result of a subsequent GET to this object is not + * the exact same as this request body, you should omit the ETag. + * + * @param mixed $calendarId + * @param string $objectUri + * @param string $calendarData + * @return string|null + */ + public function updateCalendarObject($calendarId, $objectUri, $calendarData) + { + throw new \Exception('Not implemented'); + } + + /** + * Deletes an existing calendar object. + * + * The object uri is only the basename, or filename and not a full path. + * + * @param mixed $calendarId + * @param string $objectUri + * @return void + */ + public function deleteCalendarObject($calendarId, $objectUri) + { + throw new \Exception('Not implemented'); + } +} \ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php new file mode 100644 index 0000000..5ee84de --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php @@ -0,0 +1,158 @@ + 'calcifer', + '{http://sabredav.org/ns}email-address' => 'calcifer@example.com', + 'uri' => '/caldav/calcifer', + ] + ]; + } + + /** + * Returns a specific principal, specified by it's path. + * The returned structure should be the exact same as from + * getPrincipalsByPrefix. + * + * @param string $path + * @return array + */ + function getPrincipalByPath($path) + { + return [ + '{DAV:}displayname' => 'calcifer', + '{http://sabredav.org/ns}email-address' => 'calcifer@example.com', + 'uri' => '/caldav/calcifer', + ]; + } + + /** + * Updates one ore more webdav properties on a principal. + * + * The list of mutations is stored in a Sabre\DAV\PropPatch object. + * To do the actual updates, you must tell this object which properties + * you're going to process with the handle() method. + * + * Calling the handle method is like telling the PropPatch object "I + * promise I can handle updating this property". + * + * Read the PropPatch documenation for more info and examples. + * + * @param string $path + * @param \Sabre\DAV\PropPatch $propPatch + * @return void + */ + function updatePrincipal($path, \Sabre\DAV\PropPatch $propPatch) + { + throw new \Exception('Not implemented'); + } + + /** + * This method is used to search for principals matching a set of + * properties. + * + * This search is specifically used by RFC3744's principal-property-search + * REPORT. You should at least allow searching on + * http://sabredav.org/ns}email-address. + * + * The actual search should be a unicode-non-case-sensitive search. The + * keys in searchProperties are the WebDAV property names, while the values + * are the property values to search on. + * + * If multiple properties are being searched on, the search should be + * AND'ed. + * + * This method should simply return an array with full principal uri's. + * + * If somebody attempted to search on a property the backend does not + * support, you should simply return 0 results. + * + * You can also just return 0 results if you choose to not support + * searching at all, but keep in mind that this may stop certain features + * from working. + * + * @param string $prefixPath + * @param array $searchProperties + * @return array + */ + function searchPrincipals($prefixPath, array $searchProperties) + { + return [ + [ + '{DAV:}displayname' => 'calcifer', + '{http://sabredav.org/ns}email-address' => 'calcifer@example.com', + 'uri' => '/caldav/calcifer', + ] + ]; + } + + /** + * Returns the list of members for a group-principal + * + * @param string $principal + * @return array + */ + function getGroupMemberSet($principal) + { + throw new \Exception('Not implemented'); + } + + /** + * Returns the list of groups a principal is a member of + * + * @param string $principal + * @return array + */ + function getGroupMembership($principal) + { + throw new \Exception('Not implemented'); + } + + /** + * Updates the list of group members for a group principal. + * + * The principals should be passed as a list of uri's. + * + * @param string $principal + * @param array $members + * @return void + */ + function setGroupMemberSet($principal, array $members) + { + throw new \Exception('Not implemented'); + } +} \ No newline at end of file From 807cfa1b55fef81567047043a03e4be44b82e868 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 15 Nov 2014 21:35:11 +0100 Subject: [PATCH 07/40] Integrate sabre.io into the EventController. Ticket #31 --- .../Controller/EventController.php | 77 +++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php index 876fecd..985f7d3 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php @@ -14,6 +14,15 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Hackspace\Bundle\CalciferBundle\Entity\Event; use Hackspace\Bundle\CalciferBundle\Form\EventType; +use Symfony\Component\HttpFoundation\Response; +use + Sabre\VObject, + Sabre\CalDAV, + Sabre\DAV, + Sabre\DAVACL, + Sabre\DAV\Exception\Forbidden, + Hackspace\Bundle\CalciferBundle\libs\CalciferCaldavBackend, + Hackspace\Bundle\CalciferBundle\libs\CalciferPrincipalBackend; /** * Event controller. @@ -22,6 +31,45 @@ use Hackspace\Bundle\CalciferBundle\Form\EventType; */ class EventController extends Controller { + /** + * Finds and displays a Event entity. + * + * @Route("/{url}", name="events_caldav", requirements={"url" : "caldav(.+)"}) + */ + public function caldavEntry() + { + // Backends + $calendarBackend = new CalciferCaldavBackend($this); + $principalBackend = new CalciferPrincipalBackend(); + // Directory structure + $tree = [ + new CalDAV\CalendarRootNode($principalBackend, $calendarBackend), + ]; + + $server = new DAV\Server($tree); + + $server->setBaseUri('/caldav'); + + /*$aclPlugin = new DAVACL\Plugin(); + $aclPlugin->allowAccessToNodesWithoutACL = false; + $server->addPlugin($aclPlugin);*/ + + /* CalDAV support */ + $caldavPlugin = new CalDAV\Plugin(); + $server->addPlugin($caldavPlugin); + + /* WebDAV-Sync plugin */ + $server->addPlugin(new DAV\Sync\Plugin()); + +// Support for html frontend + $browser = new DAV\Browser\Plugin(); + $server->addPlugin($browser); + +// And off we go! + $server->exec(); + return new Response(); + } + /** * Lists all Event entities. @@ -35,20 +83,21 @@ class EventController extends Controller $em = $this->getDoctrine()->getManager(); $now = new \DateTime(); - $now->setTime(0,0,0); + $now->setTime(0, 0, 0); /** @var QueryBuilder $qb */ $qb = $em->createQueryBuilder(); - $qb ->select(array('e')) + $qb->select(array('e')) ->from('CalciferBundle:Event', 'e') ->where('e.startdate >= :startdate') ->orderBy('e.startdate') - ->setParameter('startdate',$now); + ->setParameter('startdate', $now); $entities = $qb->getQuery()->execute(); return array( 'entities' => $entities, ); } + /** * Creates a new Event entity. * @@ -117,7 +166,7 @@ class EventController extends Controller } return array( - 'entity' => $entity + 'entity' => $entity ); } @@ -144,7 +193,7 @@ class EventController extends Controller } return array( - 'entity' => $entity, + 'entity' => $entity, ); } @@ -207,7 +256,7 @@ class EventController extends Controller $startdate = new \DateTime($startdate); $entity->startdate = $startdate; } - $entity->slug = $entity->generateSlug($entity->summary,$em); + $entity->slug = $entity->generateSlug($entity->summary, $em); $enddate = $request->get('enddate'); if (strlen($enddate) > 0) { @@ -246,7 +295,7 @@ class EventController extends Controller if (strlen($location_lon) > 0) { $location_obj->lon = $location_lon; } - $location_obj->slug = $location_obj->generateSlug($location_obj->name,$em); + $location_obj->slug = $location_obj->generateSlug($location_obj->name, $em); $em->persist($location_obj); $em->flush(); $entity->setLocation($location_obj); @@ -267,7 +316,7 @@ class EventController extends Controller } else { $tag_obj = new Tag(); $tag_obj->name = $tag; - $tag_obj->slug = $tag_obj->generateSlug($tag_obj->name,$em); + $tag_obj->slug = $tag_obj->generateSlug($tag_obj->name, $em); $em->persist($tag_obj); $em->flush(); $entity->addTag($tag_obj); @@ -284,7 +333,8 @@ class EventController extends Controller * @Method({"GET", "POST"}) * @Template("CalciferBundle:Event:delete.html.twig") */ - public function deleteAction(Request $request, $slug) { + public function deleteAction(Request $request, $slug) + { /** @var EntityManager $em */ $em = $this->getDoctrine()->getManager(); @@ -299,7 +349,7 @@ class EventController extends Controller } - $confirmation = $request->get('confirmation',false); + $confirmation = $request->get('confirmation', false); if (($request->getMethod() == 'POST') && ($confirmation)) { $em->remove($entity); @@ -309,7 +359,7 @@ class EventController extends Controller } return array( - 'entity' => $entity, + 'entity' => $entity, ); } @@ -321,7 +371,8 @@ class EventController extends Controller * @Method("GET") * @Template("CalciferBundle:Event:edit.html.twig") */ - public function copyAction(Request $request, $slug) { + public function copyAction(Request $request, $slug) + { /** @var EntityManager $em */ $em = $this->getDoctrine()->getManager(); @@ -338,7 +389,7 @@ class EventController extends Controller $entity->id = null; return array( - 'entity' => $entity, + 'entity' => $entity, ); } From d5773b8c6ea0fd5fb56d815134a6a44c866815ee Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Mon, 17 Nov 2014 22:57:04 +0100 Subject: [PATCH 08/40] Strip new lines for ical files. --- src/Hackspace/Bundle/CalciferBundle/Entity/Event.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php index eb23903..8c0c4c7 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php @@ -5,7 +5,7 @@ namespace Hackspace\Bundle\CalciferBundle\Entity; use Doctrine\ORM\Mapping as ORM; -use Jsvrcek\ICS\Model\Description\Location; +use Jsvrcek\ICS\Model\Description\Location As EventLocation; use Symfony\Component\Validator\Constraints\DateTime; use Jsvrcek\ICS\Model\Calendar; use Jsvrcek\ICS\Model\CalendarEvent; @@ -151,7 +151,7 @@ class Event extends BaseEntity $event->setSummary($this->summary); $event->setUrl($this->url); if ($this->location instanceof Location) { - $location = new Location(); + $location = new EventLocation(); $location->setName($this->location->name); $event->setLocations([$location]); if (\is_float($this->location->lon) && \is_float($this->location->lat)) { @@ -161,7 +161,7 @@ class Event extends BaseEntity $event->setGeo($geo); } } - $event->setDescription($this->description); + $event->setDescription(str_replace("\r","",str_replace("\n",'\n',$this->description))); return $event; } } From e75020e9da3ce1b712b0ffce320b945dfe5a03a7 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Mon, 17 Nov 2014 22:58:02 +0100 Subject: [PATCH 09/40] Encapsulate the event into a calendar. --- .../libs/CalciferCaldavBackend.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php index cf5f95e..358111e 100644 --- a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php +++ b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php @@ -8,7 +8,8 @@ namespace Hackspace\Bundle\CalciferBundle\libs; - +use Jsvrcek\ICS\Model\Calendar; +use Jsvrcek\ICS\CalendarExport; use Jsvrcek\ICS\CalendarStream; use Jsvrcek\ICS\Model\CalendarEvent; use Jsvrcek\ICS\Utility\Formatter; @@ -135,11 +136,19 @@ class CalciferCaldavBackend extends AbstractBackend { /** @var CalendarEvent $calendar_event */ $calendar_event = $event->ConvertToCalendarEvent(); - $calendar_data = $this->FormatCalendarEvent($calendar_event); + $calendar = new Calendar(); + $calendar->setProdId('-//My Company//Cool Calendar App//EN'); + $calendar->addEvent($calendar_event); + $calendarExport = new CalendarExport(new CalendarStream, new Formatter()); + $calendarExport->addCalendar($calendar); + + //output .ics formatted text + $calendar_data = $calendarExport->getStream(); + $event_data = [ 'id' => $event->id, - 'uri' => $event->slug, + 'uri' => $event->slug . '.ics', 'lastmodified' => $event->startdate, 'etag' => '"' . sha1($calendar_data) . '"', 'calendarid' => 1, @@ -234,7 +243,7 @@ class CalciferCaldavBackend extends AbstractBackend $repo = $em->getRepository('CalciferBundle:Event'); /** @var Event $entity */ - $event = $repo->findOneBy(['slug' => $objectUri]); + $event = $repo->findOneBy(['slug' => substr($objectUri,0,strlen($objectUri) - 4)]); if (!($event instanceof Event)) { throw $this->controller->createNotFoundException('Unable to find Event entity.'); From b5d22c0bbc077061ecd8500c710d71cd69fa5b8d Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Thu, 20 Nov 2014 15:46:58 +0100 Subject: [PATCH 10/40] Add the UID to the ical file. This also fixes the caldavs issues. Fixes #33,#31 --- src/Hackspace/Bundle/CalciferBundle/Entity/Event.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php index 8c0c4c7..1ae5a6e 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php @@ -150,6 +150,7 @@ class Event extends BaseEntity $event->setEnd($this->enddate); $event->setSummary($this->summary); $event->setUrl($this->url); + $event->setUid($this->id); if ($this->location instanceof Location) { $location = new EventLocation(); $location->setName($this->location->name); From a77fea9c362340e335e2648effec1f8e49b89437 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Thu, 20 Nov 2014 15:47:46 +0100 Subject: [PATCH 11/40] Show all events. --- .../Bundle/CalciferBundle/libs/CalciferCaldavBackend.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php index 358111e..f5f96f9 100644 --- a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php +++ b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php @@ -204,8 +204,7 @@ class CalciferCaldavBackend extends AbstractBackend $qb->select(array('e')) ->from('CalciferBundle:Event', 'e') ->where('e.startdate >= :startdate') - ->orderBy('e.startdate') - ->setParameter('startdate', $now); + ->orderBy('e.startdate'); $entities = $qb->getQuery()->execute(); if (count($entities) > 0) { From 827007437b1ed5f3f8ff8bba71a4263ac82c7c8d Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Thu, 20 Nov 2014 15:52:54 +0100 Subject: [PATCH 12/40] Fix the query --- .../Bundle/CalciferBundle/libs/CalciferCaldavBackend.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php index f5f96f9..f2003f8 100644 --- a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php +++ b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferCaldavBackend.php @@ -203,7 +203,6 @@ class CalciferCaldavBackend extends AbstractBackend $qb = $em->createQueryBuilder(); $qb->select(array('e')) ->from('CalciferBundle:Event', 'e') - ->where('e.startdate >= :startdate') ->orderBy('e.startdate'); $entities = $qb->getQuery()->execute(); From a5b2f118a2e2a2466d0076ce8b21de4fccbe32c5 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Thu, 20 Nov 2014 16:19:11 +0100 Subject: [PATCH 13/40] Add /all.ics Fixes #32 --- .../Controller/EventController.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php index 985f7d3..9e5723f 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php @@ -15,6 +15,10 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Hackspace\Bundle\CalciferBundle\Entity\Event; use Hackspace\Bundle\CalciferBundle\Form\EventType; use Symfony\Component\HttpFoundation\Response; +use Jsvrcek\ICS\Model\Calendar; +use Jsvrcek\ICS\Utility\Formatter; +use Jsvrcek\ICS\CalendarStream; +use Jsvrcek\ICS\CalendarExport; use Sabre\VObject, Sabre\CalDAV, @@ -70,6 +74,49 @@ class EventController extends Controller return new Response(); } + /** + * Lists all Event entities as ICS. + * + * @Route("/all.ics", name="events_ics") + * @Method("GET") + * @Template() + */ + public function allEventsAsICSAction() + { + $em = $this->getDoctrine()->getManager(); + + $now = new \DateTime(); + $now->setTime(0, 0, 0); + /** @var QueryBuilder $qb */ + $qb = $em->createQueryBuilder(); + $qb->select(array('e')) + ->from('CalciferBundle:Event', 'e') + ->where('e.startdate >= :startdate') + ->orderBy('e.startdate') + ->setParameter('startdate', $now); + $entities = $qb->getQuery()->execute(); + + $calendar = new Calendar(); + $calendar->setProdId('-//My Company//Cool Calendar App//EN'); + + foreach ($entities as $entity) { + /** @var Event $entity */ + $event = $entity->ConvertToCalendarEvent(); + $calendar->addEvent($event); + } + + $calendarExport = new CalendarExport(new CalendarStream, new Formatter()); + $calendarExport->addCalendar($calendar); + + //output .ics formatted text + $result = $calendarExport->getStream(); + + $response = new Response($result); + $response->headers->set('Content-Type', 'text/calendar'); + + return $response; + } + /** * Lists all Event entities. From 10931fa07b18475733e317617143ad82a8fc39b2 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 22 Nov 2014 17:08:25 +0100 Subject: [PATCH 14/40] Add the tags as categories in the ICS-files. Fixes #34 --- app/SymfonyRequirements.php | 14 ++- app/check.php | 2 +- composer.json | 2 +- composer.lock | 109 +++++++++--------- .../Bundle/CalciferBundle/Entity/Event.php | 6 + 5 files changed, 77 insertions(+), 56 deletions(-) diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php index 56bd35d..e14d496 100644 --- a/app/SymfonyRequirements.php +++ b/app/SymfonyRequirements.php @@ -440,8 +440,8 @@ class SymfonyRequirements extends RequirementCollection } $this->addRequirement( - isset($timezones[date_default_timezone_get()]), - sprintf('Configured default timezone "%s" must be supported by your installation of PHP', date_default_timezone_get()), + isset($timezones[@date_default_timezone_get()]), + sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()), 'Your default timezone is not supported by PHP. Check for typos in your php.ini file and have a look at the list of deprecated timezones at http://php.net/manual/en/timezones.others.php.' ); } @@ -530,6 +530,16 @@ class SymfonyRequirements extends RequirementCollection 'Install the PCRE extension (version 8.0+).' ); + if (extension_loaded('mbstring')) { + $this->addPhpIniRequirement( + 'mbstring.func_overload', + create_function('$cfgValue', 'return (int) $cfgValue !== 0;'), + true, + 'string functions should not be overloaded', + 'Set "mbstring.func_overload" to 0 in php.ini* to disable function overloading by the mbstring extension.' + ); + } + /* optional recommendations follow */ $this->addRecommendation( diff --git a/app/check.php b/app/check.php index bb0a20e..90bad4a 100644 --- a/app/check.php +++ b/app/check.php @@ -110,7 +110,7 @@ function echo_style($style, $message) ); $supports = has_color_support(); - echo ($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); + echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); } function echo_block($style, $title, $message) diff --git a/composer.json b/composer.json index faa8d52..08bbdc0 100755 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "incenteev/composer-parameter-handler": "~2.0", "jquery/jquery": "1.10.*", "knplabs/knp-markdown-bundle": "~1.3", - "enko/ics": "~0.1", + "enko/ics": "~0.2", "doctrine/migrations": "dev-master", "doctrine/doctrine-migrations-bundle": "dev-master", "jbroadway/urlify" : "~1.0", diff --git a/composer.lock b/composer.lock index 6d814aa..923acf9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "c0dd295d10e8821f679de1dc090aa14e", + "hash": "6771cfbdeebb8bc4a8a5ca0071bbf312", "packages": [ { "name": "doctrine/annotations", @@ -732,16 +732,16 @@ }, { "name": "enko/ics", - "version": "0.1.0", + "version": "0.2.0", "source": { "type": "git", "url": "https://github.com/enko/ICS.git", - "reference": "60416fc3842a7b4ee4f0938b8c35c96b402fee32" + "reference": "b1e4f9a725476cc36d5447c219cdb9bc06e62518" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/enko/ICS/zipball/60416fc3842a7b4ee4f0938b8c35c96b402fee32", - "reference": "60416fc3842a7b4ee4f0938b8c35c96b402fee32", + "url": "https://api.github.com/repos/enko/ICS/zipball/b1e4f9a725476cc36d5447c219cdb9bc06e62518", + "reference": "b1e4f9a725476cc36d5447c219cdb9bc06e62518", "shasum": "" }, "require": { @@ -780,7 +780,7 @@ "ical", "multi-byte safe" ], - "time": "2014-07-30 23:43:46" + "time": "2014-11-22 15:55:19" }, { "name": "enko/relativedateparser", @@ -1285,16 +1285,16 @@ }, { "name": "sabre/dav", - "version": "2.0.5", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/fruux/sabre-dav.git", - "reference": "e390d39ebfc701543459370e89a16d2d71910bda" + "reference": "0f192d4844b99552542ed086940813210b9ddc19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/e390d39ebfc701543459370e89a16d2d71910bda", - "reference": "e390d39ebfc701543459370e89a16d2d71910bda", + "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/0f192d4844b99552542ed086940813210b9ddc19", + "reference": "0f192d4844b99552542ed086940813210b9ddc19", "shasum": "" }, "require": { @@ -1308,13 +1308,14 @@ "ext-simplexml": "*", "ext-spl": "*", "php": ">=5.4.1", - "sabre/event": "~1.0.0", - "sabre/http": "~2.0.2", - "sabre/vobject": "~3.3.0" + "sabre/event": "~2.0.0", + "sabre/http": "~3.0.0", + "sabre/vobject": "~3.3.4" }, "require-dev": { - "evert/phpdoc-md": "~0.0.7", - "phpunit/phpunit": "~4.2" + "evert/phpdoc-md": "~0.1.0", + "phpunit/phpunit": "~4.2", + "squizlabs/php_codesniffer": "~1.5.3" }, "suggest": { "ext-curl": "*", @@ -1346,7 +1347,7 @@ } ], "description": "WebDAV Framework for PHP", - "homepage": "http://code.google.com/p/sabredav/", + "homepage": "http://sabre.io/", "keywords": [ "CalDAV", "CardDAV", @@ -1354,20 +1355,20 @@ "framework", "iCalendar" ], - "time": "2014-10-14 16:14:28" + "time": "2014-11-20 04:52:55" }, { "name": "sabre/event", - "version": "1.0.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/fruux/sabre-event.git", - "reference": "5ee3adf5441c2fe53b8ceacff6db81e621ee884c" + "reference": "f33d60742d7dff63d3722d0f70016704bf32e8db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruux/sabre-event/zipball/5ee3adf5441c2fe53b8ceacff6db81e621ee884c", - "reference": "5ee3adf5441c2fe53b8ceacff6db81e621ee884c", + "url": "https://api.github.com/repos/fruux/sabre-event/zipball/f33d60742d7dff63d3722d0f70016704bf32e8db", + "reference": "f33d60742d7dff63d3722d0f70016704bf32e8db", "shasum": "" }, "require": { @@ -1375,8 +1376,8 @@ }, "type": "library", "autoload": { - "psr-0": { - "Sabre\\Event": "lib/" + "psr-4": { + "Sabre\\Event\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1386,31 +1387,35 @@ "authors": [ { "name": "Evert Pot", - "email": "evert@rooftopsolutions.nl", - "homepage": "http://www.rooftopsolutions.nl/", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", "role": "Developer" } ], - "description": "The sabre/event library provides utilities for lightweight event-based programming", - "homepage": "http://sabre.io/event", + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", "keywords": [ "EventEmitter", - "events" + "events", + "hooks", + "plugin", + "promise", + "signal" ], - "time": "2014-06-12 16:34:49" + "time": "2014-10-06 23:26:48" }, { "name": "sabre/http", - "version": "2.0.4", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/fruux/sabre-http.git", - "reference": "c4c24f547a5509c6c661b11ecf4ff524d2bf6a44" + "reference": "897fdb22c3b195615bd7e2c8aadd1a1354884981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruux/sabre-http/zipball/c4c24f547a5509c6c661b11ecf4ff524d2bf6a44", - "reference": "c4c24f547a5509c6c661b11ecf4ff524d2bf6a44", + "url": "https://api.github.com/repos/fruux/sabre-http/zipball/897fdb22c3b195615bd7e2c8aadd1a1354884981", + "reference": "897fdb22c3b195615bd7e2c8aadd1a1354884981", "shasum": "" }, "require": { @@ -1427,8 +1432,8 @@ }, "type": "library", "autoload": { - "psr-0": { - "Sabre\\HTTP": "lib/" + "psr-4": { + "Sabre\\HTTP\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1448,20 +1453,20 @@ "keywords": [ "http" ], - "time": "2014-07-14 18:13:13" + "time": "2014-10-10 01:10:11" }, { "name": "sabre/vobject", - "version": "3.3.3", + "version": "3.3.4", "source": { "type": "git", "url": "https://github.com/fruux/sabre-vobject.git", - "reference": "de508f160e811c09b5e651909eb20b9e058a043c" + "reference": "e7cbc59a7a77325dfa32924865e1802c9216a3e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/de508f160e811c09b5e651909eb20b9e058a043c", - "reference": "de508f160e811c09b5e651909eb20b9e058a043c", + "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/e7cbc59a7a77325dfa32924865e1802c9216a3e0", + "reference": "e7cbc59a7a77325dfa32924865e1802c9216a3e0", "shasum": "" }, "require": { @@ -1514,21 +1519,21 @@ "jCard", "vCard" ], - "time": "2014-10-09 15:59:25" + "time": "2014-11-19 22:15:24" }, { "name": "sensio/distribution-bundle", - "version": "v3.0.8", + "version": "v3.0.9", "target-dir": "Sensio/Bundle/DistributionBundle", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", - "reference": "bc5e96bb4faf6bee7121085951d11b89488952f5" + "reference": "82d85b032db66163568ad988e630e5ad74138c72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/bc5e96bb4faf6bee7121085951d11b89488952f5", - "reference": "bc5e96bb4faf6bee7121085951d11b89488952f5", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/82d85b032db66163568ad988e630e5ad74138c72", + "reference": "82d85b032db66163568ad988e630e5ad74138c72", "shasum": "" }, "require": { @@ -1567,7 +1572,7 @@ "configuration", "distribution" ], - "time": "2014-11-03 21:16:34" + "time": "2014-11-21 15:36:24" }, { "name": "sensio/framework-extra-bundle", @@ -1903,16 +1908,16 @@ }, { "name": "symfony/symfony", - "version": "v2.5.6", + "version": "v2.5.7", "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", - "reference": "1a1b1e528935f15dd76169f8b1dc3ef97f0d6210" + "reference": "dd4254fc39a702af22cd886a6790769541469da1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/symfony/zipball/1a1b1e528935f15dd76169f8b1dc3ef97f0d6210", - "reference": "1a1b1e528935f15dd76169f8b1dc3ef97f0d6210", + "url": "https://api.github.com/repos/symfony/symfony/zipball/dd4254fc39a702af22cd886a6790769541469da1", + "reference": "dd4254fc39a702af22cd886a6790769541469da1", "shasum": "" }, "require": { @@ -1973,7 +1978,7 @@ "ircmaxell/password-compat": "1.0.*", "monolog/monolog": "~1.3", "ocramius/proxy-manager": ">=0.3.1,<0.6-dev", - "propel/propel1": "1.6.*" + "propel/propel1": "~1.6" }, "type": "library", "extra": { @@ -2012,7 +2017,7 @@ "keywords": [ "framework" ], - "time": "2014-10-24 06:55:39" + "time": "2014-11-20 16:00:03" }, { "name": "twig/extensions", diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php index 1ae5a6e..d15420c 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php @@ -151,6 +151,12 @@ class Event extends BaseEntity $event->setSummary($this->summary); $event->setUrl($this->url); $event->setUid($this->id); + if (count($this->tags) > 0) { + $categories = []; + foreach($this->tags as $tag) { + $event->addCategory($tag->name); + } + } if ($this->location instanceof Location) { $location = new EventLocation(); $location->setName($this->location->name); From bb577e453b99e3588322fb4aae4d365c754e5f87 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 22 Nov 2014 21:14:12 +0100 Subject: [PATCH 15/40] Match the new interface for sabre.io --- .../Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php index 5ee84de..aecf15b 100644 --- a/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php +++ b/src/Hackspace/Bundle/CalciferBundle/libs/CalciferPrincipalBackend.php @@ -109,7 +109,7 @@ class CalciferPrincipalBackend extends DAVACL\PrincipalBackend\AbstractBackend * @param array $searchProperties * @return array */ - function searchPrincipals($prefixPath, array $searchProperties) + function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') { return [ [ From ddd745e19075c9f0b56c4fbe922bb64406bc822b Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 22 Nov 2014 21:14:25 +0100 Subject: [PATCH 16/40] Remove the console output. --- .../Bundle/CalciferBundle/Command/GenerateEventsCommand.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php b/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php index c74573a..e19539b 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php +++ b/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php @@ -38,8 +38,6 @@ class GenerateEventsCommand extends ContainerAwareCommand $now = new \DateTime(); $end = new \DateTime(); $end->add($duration); - $output->writeln(sprintf("Generating Dates from %s to %s",$now->format('Y-m-d'),$end->format('Y-m-d'))); - $output->writeln("Fetching repeating events"); /** @var EntityManager $entityManager */ $entityManager = $this->getContainer()->get('doctrine')->getManager(); $repo = $entityManager->getRepository('CalciferBundle:RepeatingEvent'); From cc9a48315f520bc735a7ed923320eb21f4e701c7 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 22 Nov 2014 21:54:47 +0100 Subject: [PATCH 17/40] Set the URI of the event as UID Fixes #35 --- src/Hackspace/Bundle/CalciferBundle/Entity/Event.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php index d15420c..94048fc 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php @@ -150,7 +150,8 @@ class Event extends BaseEntity $event->setEnd($this->enddate); $event->setSummary($this->summary); $event->setUrl($this->url); - $event->setUid($this->id); + $uid = sprintf("https://%s/termine/%s",$_SERVER['HTTP_HOST'],$this->slug); + $event->setUid($uid); if (count($this->tags) > 0) { $categories = []; foreach($this->tags as $tag) { From 97a71875e9e4b1fd5526291470df6fad622a307b Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 21 Mar 2015 14:20:17 +0100 Subject: [PATCH 18/40] This sorta fixes #19 --- .../Bundle/CalciferBundle/Command/GenerateEventsCommand.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php b/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php index e19539b..005664e 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php +++ b/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php @@ -41,10 +41,13 @@ class GenerateEventsCommand extends ContainerAwareCommand /** @var EntityManager $entityManager */ $entityManager = $this->getContainer()->get('doctrine')->getManager(); $repo = $entityManager->getRepository('CalciferBundle:RepeatingEvent'); - $entities = $repo->findAll(); + $entities = $repo->findBy([],['id' => 'asc']); foreach($entities as $entity) { /** @var RepeatingEvent $entity */ $next_date = is_null($entity->nextdate) ? new DateTime() : $entity->nextdate; + /** This is a fuggly hack. It would be best to store the named timezone also in the + * database to avoid problems with daylight savings. */ + $next_date->setTimezone(new \DateTimeZone('Europe/Berlin')); $parser = new RelativeDateParser($entity->repeating_pattern,$next_date,'de'); $event = null; while (($next_date = $parser->getNext()) < $end) { From 175f99809d9ff6a9e5b32619db3bf6f7ad2341f9 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 21 Mar 2015 15:55:49 +0100 Subject: [PATCH 19/40] Prevent an update of a location when there is a location with the same name. Fixes #23 --- .../Controller/LocationController.php | 14 ++++++++++++-- .../Resources/views/Location/edit.html.twig | 11 +++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php index 64b174a..a9ec487 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php @@ -143,8 +143,18 @@ class LocationController extends Controller } if ($location->name != $request->get('name')) { - $location->name = $request->get('name'); - $location->slug = $location->generateSlug($location->name, $em); + // someone changed the name of the location, lets check if the location already exists + $new_location = $repo->findOneBy(['name' => $request->get('name')]); + if (is_null($new_location)) { + $location->name = $request->get('name'); + $location->slug = $location->generateSlug($location->name, $em); + } else { + $request->getSession()->getFlashBag()->add( + 'error', + 'Ort mit diesem Namen existiert bereits.' + ); + return $this->redirect($this->generateUrl('location_edit', array('slug' => $location->slug))); + } } $location->streetaddress = $request->get('streetaddress'); $location->streetnumber = $request->get('streetnumber'); diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig index 6eb61de..5142616 100644 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig @@ -29,6 +29,17 @@
+ {% set errors = app.session.flashbag.get('error') %} + {% if errors|length > 0 %} +
+
Bitte korrigiere folgende Fehler:
+
    + {% for flashMessage in errors %} +
  • {{ flashMessage }}
  • + {% endfor %} +
+
+ {% endif %}
From 9877b70ef97417a47a3b50d8af43a9dbde11d476 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sun, 22 Mar 2015 09:38:28 +0100 Subject: [PATCH 20/40] Convert all tags to lowercase. Fixes #41 --- .../Bundle/CalciferBundle/Controller/EventController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php index 9e5723f..320c931 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php @@ -351,7 +351,7 @@ class EventController extends Controller $tags = $request->get('tags'); if (strlen($tags) > 0) { - $tags = explode(',', $tags); + $tags = explode(',', strtolower($tags)); $em = $this->getDoctrine()->getManager(); $repo = $em->getRepository('CalciferBundle:Tag'); $entity->clearTags(); From 1715f27f44449f1587691c7ff50f5e508f6aff81 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sun, 29 Mar 2015 19:17:49 +0200 Subject: [PATCH 21/40] Added a about page. Fixes #39,#14 --- .../Controller/DefaultController.php | 6 +- .../Resources/views/Default/index.html.twig | 65 ++++++++++++++++++- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/DefaultController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/DefaultController.php index acb65c9..1f4cce6 100644 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/DefaultController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/DefaultController.php @@ -9,11 +9,11 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; class DefaultController extends Controller { /** - * @Route("/hello/{name}") + * @Route("/über", name="about_calcifer") * @Template() */ - public function indexAction($name) + public function indexAction() { - return array('name' => $name); + return []; } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Default/index.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Default/index.html.twig index 4ce626e..26822d4 100644 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Default/index.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Default/index.html.twig @@ -1 +1,64 @@ -Hello {{ name }}! +{% extends 'CalciferBundle::layout.html.twig' %} + +{% block body -%} +
+

+ Über Calcifer +

+
+
+
+
+
+
+
+ {% image '@CalciferBundle/Resources/assets/images/logo.png' %} + Eine Zeichnung von Calcifer. Gezeichnet von simply-Sylvan (http://simply-sylvan.deviantart.com/art/Calcifer-Purple-176746086) + {% endimage %} +
+
+ Calcifer + +
+ Gezeichnet von simply-Sylvan. +
+
+
+
+
+

Calcifer ist ein Daemon aus dem Anime „Das wandelnde + Schloss“, + der sich darum kümmert das sich Howls Schloss weiter bewegt. Diese Terminverwaltung soll dafür + sorgen + das sich der Hackspace Jena auch weiter bewegt und + viele tolle + Termine statfinden.

+ +

+ Die Software wurde mit Symfony2 und Semantic UI gestrickt. Den + Quellcode findest du auf der Phabricator + Instanz des + Hackspace Jena oder auf Github. +

+ +

+ Solltest du Probleme mit Calcifer haben, kannst du entweder über Phabricator oder Github ein Ticket + anlegen. + Alternativ kannst du auch im Chat des + Hackspace + Jena Probleme melden. +

+ +
+
+
+
+{% endblock %} \ No newline at end of file From 2027b94179e24e2556095f19ce9d8d17d4645c67 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sun, 29 Mar 2015 19:33:23 +0200 Subject: [PATCH 22/40] Update Semantic Fixes #40,#24 --- .../Resources/assets/css/events.scss | 15 + .../Resources/assets/css/main.scss | 3 +- .../Resources/assets/js/events.js | 35 +- .../Resources/views/Event/edit.html.twig | 10 +- .../Resources/views/Event/event_box.html.twig | 104 +- .../views/Event/event_form.html.twig | 258 +- .../Resources/views/Event/index.html.twig | 138 +- .../Resources/views/Event/show.html.twig | 2 +- .../Resources/views/Location/edit.html.twig | 276 +- .../views/RepeatingEvent/edit.html.twig | 16 +- .../views/RepeatingEvent/index.html.twig | 78 +- .../views/RepeatingEvent/new.html.twig | 10 +- .../repeating_event_form.html.twig | 118 +- .../repeating_patterns.html.twig | 30 +- .../Resources/views/layout.html.twig | 29 +- .../Resources/views/navigation.html.twig | 13 +- web/css/semantic.min.css | 14 - web/css/semantic.scss | 15366 -------- web/semantic/.csscomb.json | 322 + web/semantic/.csslintrc | 18 + web/semantic/.gitignore | 36 + web/semantic/.jshintrc | 38 + web/semantic/CONTRIBUTING.md | 16 + web/semantic/LICENSE.md | 7 + web/semantic/README.md | 85 + web/semantic/RELEASE-NOTES.md | 1473 + web/semantic/bower.json | 29 + web/semantic/composer.json | 24 + web/semantic/dist/components/accordion.css | 256 + web/semantic/dist/components/accordion.js | 578 + .../dist/components/accordion.min.css | 10 + web/semantic/dist/components/accordion.min.js | 11 + web/semantic/dist/components/ad.css | 276 + web/semantic/dist/components/ad.min.css | 10 + web/semantic/dist/components/api.js | 871 + web/semantic/dist/components/api.min.js | 11 + web/semantic/dist/components/breadcrumb.css | 124 + .../dist/components/breadcrumb.min.css | 10 + web/semantic/dist/components/button.css | 2391 ++ web/semantic/dist/components/button.min.css | 10 + web/semantic/dist/components/card.css | 909 + web/semantic/dist/components/card.min.css | 10 + web/semantic/dist/components/checkbox.css | 513 + web/semantic/dist/components/checkbox.js | 509 + web/semantic/dist/components/checkbox.min.css | 10 + web/semantic/dist/components/checkbox.min.js | 11 + web/semantic/dist/components/comment.css | 259 + web/semantic/dist/components/comment.min.css | 10 + web/semantic/dist/components/dimmer.css | 186 + web/semantic/dist/components/dimmer.js | 669 + web/semantic/dist/components/dimmer.min.css | 10 + web/semantic/dist/components/dimmer.min.js | 11 + web/semantic/dist/components/divider.css | 241 + web/semantic/dist/components/divider.min.css | 10 + web/semantic/dist/components/dropdown.css | 1103 + web/semantic/dist/components/dropdown.js | 1795 + web/semantic/dist/components/dropdown.min.css | 10 + web/semantic/dist/components/dropdown.min.js | 11 + web/semantic/dist/components/feed.css | 276 + web/semantic/dist/components/feed.min.css | 10 + web/semantic/dist/components/flag.css | 1024 + web/semantic/dist/components/flag.min.css | 10 + web/semantic/dist/components/form.css | 891 + web/semantic/dist/components/form.js | 1118 + web/semantic/dist/components/form.min.css | 10 + web/semantic/dist/components/form.min.js | 11 + web/semantic/dist/components/grid.css | 1871 + web/semantic/dist/components/grid.min.css | 10 + web/semantic/dist/components/header.css | 596 + web/semantic/dist/components/header.min.css | 10 + web/semantic/dist/components/icon.css | 2467 ++ web/semantic/dist/components/icon.min.css | 10 + web/semantic/dist/components/image.css | 288 + web/semantic/dist/components/image.min.css | 10 + web/semantic/dist/components/input.css | 439 + web/semantic/dist/components/input.min.css | 10 + web/semantic/dist/components/item.css | 456 + web/semantic/dist/components/item.min.css | 10 + web/semantic/dist/components/label.css | 963 + web/semantic/dist/components/label.min.css | 10 + web/semantic/dist/components/list.css | 878 + web/semantic/dist/components/list.min.css | 10 + web/semantic/dist/components/loader.css | 284 + web/semantic/dist/components/loader.min.css | 10 + web/semantic/dist/components/menu.css | 1608 + web/semantic/dist/components/menu.min.css | 10 + web/semantic/dist/components/message.css | 421 + web/semantic/dist/components/message.min.css | 10 + web/semantic/dist/components/modal.css | 432 + web/semantic/dist/components/modal.js | 860 + web/semantic/dist/components/modal.min.css | 10 + web/semantic/dist/components/modal.min.js | 11 + web/semantic/dist/components/nag.css | 148 + web/semantic/dist/components/nag.js | 477 + web/semantic/dist/components/nag.min.css | 10 + web/semantic/dist/components/nag.min.js | 11 + web/semantic/dist/components/popup.css | 293 + web/semantic/dist/components/popup.js | 1224 + web/semantic/dist/components/popup.min.css | 10 + web/semantic/dist/components/popup.min.js | 11 + web/semantic/dist/components/progress.css | 461 + web/semantic/dist/components/progress.js | 785 + web/semantic/dist/components/progress.min.css | 10 + web/semantic/dist/components/progress.min.js | 11 + web/semantic/dist/components/rail.css | 124 + web/semantic/dist/components/rail.min.css | 10 + web/semantic/dist/components/rating.css | 251 + web/semantic/dist/components/rating.js | 451 + web/semantic/dist/components/rating.min.css | 10 + web/semantic/dist/components/rating.min.js | 11 + web/semantic/dist/components/reset.css | 429 + web/semantic/dist/components/reset.min.css | 10 + web/semantic/dist/components/reveal.css | 293 + web/semantic/dist/components/reveal.min.css | 10 + web/semantic/dist/components/search.css | 329 + web/semantic/dist/components/search.js | 1096 + web/semantic/dist/components/search.min.css | 10 + web/semantic/dist/components/search.min.js | 11 + web/semantic/dist/components/segment.css | 635 + web/semantic/dist/components/segment.min.css | 10 + web/semantic/dist/components/shape.css | 154 + web/semantic/dist/components/shape.js | 830 + web/semantic/dist/components/shape.min.css | 10 + web/semantic/dist/components/shape.min.js | 11 + web/semantic/dist/components/sidebar.css | 625 + web/semantic/dist/components/sidebar.js | 1089 + web/semantic/dist/components/sidebar.min.css | 10 + web/semantic/dist/components/sidebar.min.js | 11 + web/semantic/dist/components/site.css | 160 + web/semantic/dist/components/site.js | 487 + web/semantic/dist/components/site.min.css | 10 + web/semantic/dist/components/site.min.js | 11 + web/semantic/dist/components/state.js | 695 + web/semantic/dist/components/state.min.js | 11 + web/semantic/dist/components/statistic.css | 409 + .../dist/components/statistic.min.css | 10 + web/semantic/dist/components/step.css | 432 + web/semantic/dist/components/step.min.css | 10 + web/semantic/dist/components/sticky.css | 79 + web/semantic/dist/components/sticky.js | 792 + web/semantic/dist/components/sticky.min.css | 10 + web/semantic/dist/components/sticky.min.js | 11 + web/semantic/dist/components/tab.css | 92 + web/semantic/dist/components/tab.js | 802 + web/semantic/dist/components/tab.min.css | 10 + web/semantic/dist/components/tab.min.js | 11 + web/semantic/dist/components/table.css | 1000 + web/semantic/dist/components/table.min.css | 10 + web/semantic/dist/components/transition.css | 1990 + web/semantic/dist/components/transition.js | 1038 + .../dist/components/transition.min.css | 10 + .../dist/components/transition.min.js | 11 + web/semantic/dist/components/video.css | 125 + web/semantic/dist/components/video.js | 540 + web/semantic/dist/components/video.min.css | 10 + web/semantic/dist/components/video.min.js | 11 + web/semantic/dist/components/visibility.js | 1032 + .../dist/components/visibility.min.js | 11 + web/semantic/dist/semantic.css | 32685 ++++++++++++++++ web/semantic/dist/semantic.js | 18881 +++++++++ web/semantic/dist/semantic.min.css | 11 + web/semantic/dist/semantic.min.js | 17 + .../dist/themes/basic/assets/fonts/icons.eot | Bin 0 -> 40166 bytes .../dist/themes/basic/assets/fonts/icons.svg | 450 + .../dist/themes/basic/assets/fonts/icons.ttf | Bin 0 -> 39924 bytes .../dist/themes/basic/assets/fonts/icons.woff | Bin 0 -> 24676 bytes .../themes/default/assets/fonts/icons.eot | Bin 0 -> 60767 bytes .../themes/default/assets/fonts/icons.otf | Bin 0 -> 93888 bytes .../themes/default/assets/fonts/icons.svg | 565 + .../themes/default/assets/fonts/icons.ttf | Bin 0 -> 122092 bytes .../themes/default/assets/fonts/icons.woff | Bin 0 -> 71508 bytes .../themes/default/assets/fonts/icons.woff2 | Bin 0 -> 56780 bytes .../themes/default/assets/images/flags.png | Bin 0 -> 28123 bytes web/semantic/examples/feed.css | 74 + web/semantic/examples/feed.html | 183 + web/semantic/examples/feed.js | 23 + web/semantic/examples/grid.css | 103 + web/semantic/examples/grid.html | 1439 + web/semantic/examples/homepage.css | 134 + web/semantic/examples/homepage.html | 315 + web/semantic/examples/homepage.js | 57 + web/semantic/examples/images/bg.jpg | Bin 0 -> 47123 bytes web/semantic/examples/images/cat.png | Bin 0 -> 109981 bytes .../images/wireframe/centered-paragraph.png | Bin 0 -> 1988 bytes .../images/wireframe/image-square.png | Bin 0 -> 6227 bytes .../examples/images/wireframe/image-text.png | Bin 0 -> 9835 bytes .../examples/images/wireframe/image.png | Bin 0 -> 7175 bytes .../images/wireframe/media-paragraph-alt.png | Bin 0 -> 2393 bytes .../images/wireframe/media-paragraph.png | Bin 0 -> 3465 bytes .../examples/images/wireframe/paragraph.png | Bin 0 -> 2476 bytes .../images/wireframe/short-paragraph.png | Bin 0 -> 1281 bytes .../images/wireframe/square-image.png | Bin 0 -> 1787 bytes .../examples/images/wireframe/text-image.png | Bin 0 -> 1924 bytes .../examples/images/wireframe/white-image.png | Bin 0 -> 5951 bytes web/semantic/examples/kitchensink.css | 49 + web/semantic/examples/kitchensink.html | 5454 +++ web/semantic/gulpfile.js | 73 + web/semantic/karma.conf.js | 85 + web/semantic/logo.png | Bin 0 -> 7348 bytes web/semantic/package.json | 89 + web/semantic/semantic.json.example | 23 + web/semantic/src/README.md | 127 + .../_site/collections/breadcrumb.overrides | 3 + .../_site/collections/breadcrumb.variables | 3 + .../src/_site/collections/form.overrides | 3 + .../src/_site/collections/form.variables | 3 + .../src/_site/collections/grid.overrides | 3 + .../src/_site/collections/grid.variables | 3 + .../src/_site/collections/menu.overrides | 3 + .../src/_site/collections/menu.variables | 3 + .../src/_site/collections/message.overrides | 3 + .../src/_site/collections/message.variables | 3 + .../src/_site/collections/table.overrides | 3 + .../src/_site/collections/table.variables | 3 + .../src/_site/elements/button.overrides | 3 + .../src/_site/elements/button.variables | 3 + .../src/_site/elements/divider.overrides | 3 + .../src/_site/elements/divider.variables | 3 + .../src/_site/elements/flag.overrides | 3 + .../src/_site/elements/flag.variables | 3 + .../src/_site/elements/header.overrides | 3 + .../src/_site/elements/header.variables | 3 + .../src/_site/elements/icon.overrides | 3 + .../src/_site/elements/icon.variables | 3 + .../src/_site/elements/image.overrides | 3 + .../src/_site/elements/image.variables | 3 + .../src/_site/elements/input.overrides | 3 + .../src/_site/elements/input.variables | 3 + .../src/_site/elements/label.overrides | 3 + .../src/_site/elements/label.variables | 3 + .../src/_site/elements/list.overrides | 3 + .../src/_site/elements/list.variables | 3 + .../src/_site/elements/loader.overrides | 3 + .../src/_site/elements/loader.variables | 3 + .../src/_site/elements/rail.overrides | 3 + .../src/_site/elements/rail.variables | 3 + .../src/_site/elements/reveal.overrides | 3 + .../src/_site/elements/reveal.variables | 3 + .../src/_site/elements/segment.overrides | 3 + .../src/_site/elements/segment.variables | 3 + .../src/_site/elements/step.overrides | 3 + .../src/_site/elements/step.variables | 3 + .../src/_site/globals/reset.overrides | 3 + .../src/_site/globals/reset.variables | 3 + web/semantic/src/_site/globals/site.overrides | 3 + web/semantic/src/_site/globals/site.variables | 3 + .../src/_site/modules/accordion.overrides | 3 + .../src/_site/modules/accordion.variables | 3 + .../src/_site/modules/chatroom.overrides | 3 + .../src/_site/modules/chatroom.variables | 3 + .../src/_site/modules/checkbox.overrides | 3 + .../src/_site/modules/checkbox.variables | 3 + .../src/_site/modules/dimmer.overrides | 3 + .../src/_site/modules/dimmer.variables | 3 + .../src/_site/modules/dropdown.overrides | 3 + .../src/_site/modules/dropdown.variables | 3 + .../src/_site/modules/modal.overrides | 3 + .../src/_site/modules/modal.variables | 3 + web/semantic/src/_site/modules/nag.overrides | 3 + web/semantic/src/_site/modules/nag.variables | 3 + .../src/_site/modules/popup.overrides | 3 + .../src/_site/modules/popup.variables | 3 + .../src/_site/modules/progress.overrides | 3 + .../src/_site/modules/progress.variables | 3 + .../src/_site/modules/rating.overrides | 3 + .../src/_site/modules/rating.variables | 3 + .../src/_site/modules/search.overrides | 3 + .../src/_site/modules/search.variables | 3 + .../src/_site/modules/shape.overrides | 3 + .../src/_site/modules/shape.variables | 3 + .../src/_site/modules/sidebar.overrides | 3 + .../src/_site/modules/sidebar.variables | 3 + .../src/_site/modules/sticky.overrides | 3 + .../src/_site/modules/sticky.variables | 3 + web/semantic/src/_site/modules/tab.overrides | 3 + web/semantic/src/_site/modules/tab.variables | 3 + .../src/_site/modules/transition.overrides | 3 + .../src/_site/modules/transition.variables | 3 + .../src/_site/modules/video.overrides | 3 + .../src/_site/modules/video.variables} | 0 web/semantic/src/_site/views/ad.overrides | 3 + web/semantic/src/_site/views/ad.variables | 3 + web/semantic/src/_site/views/card.overrides | 3 + web/semantic/src/_site/views/card.variables | 3 + .../src/_site/views/comment.overrides | 3 + .../src/_site/views/comment.variables | 3 + web/semantic/src/_site/views/feed.overrides | 3 + web/semantic/src/_site/views/feed.variables | 3 + web/semantic/src/_site/views/item.overrides | 3 + web/semantic/src/_site/views/item.variables | 3 + .../src/_site/views/statistic.overrides | 3 + .../src/_site/views/statistic.variables | 3 + web/semantic/src/definitions/behaviors/api.js | 871 + .../src/definitions/behaviors/colorize.js | 272 + .../src/definitions/behaviors/form.js | 1118 + .../src/definitions/behaviors/state.js | 695 + .../src/definitions/behaviors/visibility.js | 1032 + .../src/definitions/behaviors/visit.js | 515 + .../definitions/collections/breadcrumb.less | 122 + .../src/definitions/collections/form.less | 894 + .../src/definitions/collections/grid.less | 1802 + .../src/definitions/collections/menu.less | 1622 + .../src/definitions/collections/message.less | 442 + .../src/definitions/collections/table.less | 1001 + .../src/definitions/elements/button.less | 2413 ++ .../src/definitions/elements/divider.less | 254 + .../src/definitions/elements/flag.less | 53 + .../src/definitions/elements/header.less | 621 + .../src/definitions/elements/icon.less | 341 + .../src/definitions/elements/image.less | 304 + .../src/definitions/elements/input.less | 429 + .../src/definitions/elements/label.less | 969 + .../src/definitions/elements/list.less | 882 + .../src/definitions/elements/loader.less | 267 + .../src/definitions/elements/rail.less | 126 + .../src/definitions/elements/reveal.less | 258 + .../src/definitions/elements/segment.less | 629 + .../src/definitions/elements/step.less | 429 + .../src/definitions/globals/reset.less | 41 + web/semantic/src/definitions/globals/site.js | 487 + .../src/definitions/globals/site.less | 162 + .../src/definitions/modules/accordion.js | 578 + .../src/definitions/modules/accordion.less | 220 + .../src/definitions/modules/checkbox.js | 509 + .../src/definitions/modules/checkbox.less | 490 + .../src/definitions/modules/dimmer.js | 669 + .../src/definitions/modules/dimmer.less | 179 + .../src/definitions/modules/dropdown.js | 1795 + .../src/definitions/modules/dropdown.less | 1040 + web/semantic/src/definitions/modules/modal.js | 860 + .../src/definitions/modules/modal.less | 438 + web/semantic/src/definitions/modules/nag.js | 477 + web/semantic/src/definitions/modules/nag.less | 159 + web/semantic/src/definitions/modules/popup.js | 1224 + .../src/definitions/modules/popup.less | 294 + .../src/definitions/modules/progress.js | 785 + .../src/definitions/modules/progress.less | 451 + .../src/definitions/modules/rating.js | 451 + .../src/definitions/modules/rating.less | 189 + .../src/definitions/modules/search.js | 1096 + .../src/definitions/modules/search.less | 339 + web/semantic/src/definitions/modules/shape.js | 830 + .../src/definitions/modules/shape.less | 152 + .../src/definitions/modules/sidebar.js | 1089 + .../src/definitions/modules/sidebar.less | 550 + .../src/definitions/modules/sticky.js | 792 + .../src/definitions/modules/sticky.less | 75 + web/semantic/src/definitions/modules/tab.js | 802 + web/semantic/src/definitions/modules/tab.less | 95 + .../src/definitions/modules/transition.js | 1038 + .../src/definitions/modules/transition.less | 80 + web/semantic/src/definitions/modules/video.js | 540 + .../src/definitions/modules/video.less | 125 + web/semantic/src/definitions/views/ad.less | 268 + web/semantic/src/definitions/views/card.less | 927 + .../src/definitions/views/comment.less | 256 + web/semantic/src/definitions/views/feed.less | 272 + web/semantic/src/definitions/views/item.less | 465 + .../src/definitions/views/statistic.less | 414 + web/semantic/src/semantic.less | 66 + web/semantic/src/theme.config.example | 90 + web/semantic/src/theme.less | 48 + .../themes/amazon/elements/button.overrides | 46 + .../themes/amazon/elements/button.variables | 57 + .../src/themes/basic/assets/fonts/icons.eot | Bin 0 -> 40166 bytes .../src/themes/basic/assets/fonts/icons.svg | 450 + .../src/themes/basic/assets/fonts/icons.ttf | Bin 0 -> 39924 bytes .../src/themes/basic/assets/fonts/icons.woff | Bin 0 -> 24676 bytes .../themes/basic/collections/table.overrides | 4 + .../themes/basic/collections/table.variables | 10 + .../themes/basic/elements/button.overrides | 4 + .../themes/basic/elements/button.variables | 44 + .../src/themes/basic/elements/icon.overrides | 189 + .../src/themes/basic/elements/icon.variables | 12 + .../src/themes/basic/elements/step.overrides | 7 + .../src/themes/basic/elements/step.variables | 10 + .../src/themes/basic/globals/reset.overrides | 5 + .../src/themes/basic/globals/reset.variables | 3 + .../themes/basic/modules/progress.overrides | 3 + .../themes/basic/modules/progress.variables | 15 + .../src/themes/basic/views/card.overrides | 4 + .../src/themes/basic/views/card.variables | 33 + .../themes/bookish/elements/header.overrides | 15 + .../themes/bookish/elements/header.variables | 37 + .../bootstrap3/elements/button.overrides} | 0 .../bootstrap3/elements/button.variables | 63 + .../themes/chubby/collections/form.overrides | 8 + .../themes/chubby/collections/form.variables | 9 + .../themes/chubby/elements/button.overrides | 21 + .../themes/chubby/elements/button.variables | 57 + .../themes/chubby/elements/header.overrides | 5 + .../themes/chubby/elements/header.variables | 21 + .../themes/chubby/modules/accordion.overrides | 7 + .../themes/chubby/modules/accordion.variables | 15 + .../src/themes/chubby/views/comment.overrides | 12 + .../src/themes/chubby/views/comment.variables | 46 + .../classic/collections/table.overrides | 3 + .../classic/collections/table.variables | 14 + .../themes/classic/elements/button.overrides | 3 + .../themes/classic/elements/button.variables | 96 + .../themes/classic/elements/header.overrides | 3 + .../themes/classic/elements/header.variables | 12 + .../themes/classic/modules/progress.overrides | 3 + .../themes/classic/modules/progress.variables | 8 + .../src/themes/classic/views/card.overrides | 98 + .../src/themes/classic/views/card.variables | 22 + .../src/themes/default/assets/fonts/icons.eot | Bin 0 -> 60767 bytes .../src/themes/default/assets/fonts/icons.svg | 565 + .../src/themes/default/assets/fonts/icons.ttf | Bin 0 -> 122092 bytes .../themes/default/assets/fonts/icons.woff | Bin 0 -> 71508 bytes .../themes/default/assets/fonts/icons.woff2 | Bin 0 -> 56780 bytes .../themes/default/assets/images/flags.png | Bin 0 -> 28123 bytes .../default/collections/breadcrumb.overrides | 3 + .../default/collections/breadcrumb.variables | 43 + .../themes/default/collections/form.overrides | 3 + .../themes/default/collections/form.variables | 193 + .../themes/default/collections/grid.overrides | 4 + .../themes/default/collections/grid.variables | 92 + .../themes/default/collections/menu.overrides | 3 + .../themes/default/collections/menu.variables | 333 + .../default/collections/message.overrides | 3 + .../default/collections/message.variables | 88 + .../default/collections/table.overrides | 3 + .../default/collections/table.variables | 228 + .../themes/default/elements/button.overrides | 3 + .../themes/default/elements/button.variables | 294 + .../themes/default/elements/divider.overrides | 3 + .../themes/default/elements/divider.variables | 54 + .../themes/default/elements/flag.overrides | 978 + .../themes/default/elements/flag.variables | 13 + .../themes/default/elements/header.overrides | 4 + .../themes/default/elements/header.variables | 147 + .../themes/default/elements/icon.overrides | 763 + .../themes/default/elements/icon.variables | 43 + .../themes/default/elements/image.overrides | 3 + .../themes/default/elements/image.variables | 42 + .../themes/default/elements/input.overrides | 3 + .../themes/default/elements/input.variables | 118 + .../themes/default/elements/label.overrides | 3 + .../themes/default/elements/label.variables | 174 + .../themes/default/elements/list.overrides | 3 + .../themes/default/elements/list.variables | 204 + .../themes/default/elements/loader.overrides | 3 + .../themes/default/elements/loader.variables | 61 + .../themes/default/elements/rail.overrides | 3 + .../themes/default/elements/rail.variables | 26 + .../themes/default/elements/reveal.overrides | 3 + .../themes/default/elements/reveal.variables | 15 + .../themes/default/elements/segment.overrides | 3 + .../themes/default/elements/segment.variables | 100 + .../themes/default/elements/step.overrides | 16 + .../themes/default/elements/step.variables | 98 + .../themes/default/globals/reset.overrides | 434 + .../themes/default/globals/reset.variables | 3 + .../src/themes/default/globals/site.overrides | 3 + .../src/themes/default/globals/site.variables | 613 + .../default/modules/accordion.overrides | 28 + .../default/modules/accordion.variables | 101 + .../themes/default/modules/chatroom.overrides | 3 + .../themes/default/modules/chatroom.variables | 3 + .../themes/default/modules/checkbox.overrides | 33 + .../themes/default/modules/checkbox.variables | 140 + .../themes/default/modules/dimmer.overrides | 3 + .../themes/default/modules/dimmer.variables | 58 + .../themes/default/modules/dropdown.overrides | 67 + .../themes/default/modules/dropdown.variables | 275 + .../themes/default/modules/modal.overrides | 3 + .../themes/default/modules/modal.variables | 145 + .../src/themes/default/modules/nag.overrides | 3 + .../src/themes/default/modules/nag.variables | 74 + .../themes/default/modules/popup.overrides | 3 + .../themes/default/modules/popup.variables | 95 + .../themes/default/modules/progress.overrides | 3 + .../themes/default/modules/progress.variables | 107 + .../themes/default/modules/rating.overrides | 68 + .../themes/default/modules/rating.variables | 65 + .../themes/default/modules/search.overrides | 3 + .../themes/default/modules/search.variables | 140 + .../themes/default/modules/shape.overrides | 3 + .../themes/default/modules/shape.variables | 35 + .../themes/default/modules/sidebar.overrides | 3 + .../themes/default/modules/sidebar.variables | 48 + .../themes/default/modules/sticky.overrides | 3 + .../themes/default/modules/sticky.variables | 12 + .../src/themes/default/modules/tab.overrides | 3 + .../src/themes/default/modules/tab.variables | 13 + .../default/modules/transition.overrides | 911 + .../default/modules/transition.variables | 10 + .../themes/default/modules/video.overrides | 3 + .../themes/default/modules/video.variables | 16 + .../src/themes/default/views/ad.overrides | 3 + .../src/themes/default/views/ad.variables | 13 + .../src/themes/default/views/card.overrides | 3 + .../src/themes/default/views/card.variables | 199 + .../themes/default/views/comment.overrides | 3 + .../themes/default/views/comment.variables | 104 + .../src/themes/default/views/feed.overrides | 3 + .../src/themes/default/views/feed.variables | 149 + .../src/themes/default/views/item.overrides | 3 + .../src/themes/default/views/item.variables | 153 + .../themes/default/views/statistic.overrides | 3 + .../themes/default/views/statistic.variables | 97 + .../src/themes/duo/elements/loader.overrides | 3 + .../src/themes/duo/elements/loader.variables | 6 + .../fixed-width/collections/grid.overrides | 3 + .../fixed-width/collections/grid.variables | 23 + .../fixed-width/modules/modal.overrides | 3 + .../fixed-width/modules/modal.variables | 37 + .../themes/flat/collections/form.overrides | 24 + .../themes/flat/collections/form.variables | 74 + .../src/themes/flat/globals/site.overrides | 3 + .../src/themes/flat/globals/site.variables | 106 + .../themes/github/collections/form.overrides | 16 + .../themes/github/collections/form.variables | 40 + .../themes/github/collections/menu.overrides | 7 + .../themes/github/collections/menu.variables | 66 + .../github/collections/message.overrides | 11 + .../github/collections/message.variables | 29 + .../themes/github/elements/button.overrides | 4 + .../themes/github/elements/button.variables | 77 + .../themes/github/elements/segment.overrides | 3 + .../themes/github/elements/segment.variables | 41 + .../src/themes/github/elements/step.overrides | 26 + .../src/themes/github/elements/step.variables | 20 + .../gmail/collections/message.overrides | 0 .../gmail/collections/message.variables | 15 + .../themes/material/elements/button.overrides | 22 + .../themes/material/elements/button.variables | 87 + .../themes/material/elements/header.overrides | 15 + .../themes/material/elements/header.variables | 21 + .../themes/material/globals/site.overrides | 0 .../themes/material/globals/site.variables | 119 + .../themes/material/modules/modal.overrides | 6 + .../themes/material/modules/modal.variables | 15 + .../themes/pulsar/elements/loader.overrides | 70 + .../themes/pulsar/elements/loader.variables | 7 + .../themes/raised/elements/button.overrides | 3 + .../themes/raised/elements/button.variables | 27 + .../themes/resetcss/globals/reset.overrides | 52 + .../themes/resetcss/globals/reset.variables | 3 + .../themes/round/elements/button.overrides | 0 .../themes/round/elements/button.variables | 138 + .../src/themes/rtl/globals/site.overrides | 6 + .../src/themes/rtl/globals/site.variables | 14 + .../themes/striped/modules/progress.overrides | 29 + .../themes/striped/modules/progress.variables | 3 + .../src/themes/timeline/views/feed.overrides | 35 + .../src/themes/timeline/views/feed.variables | 40 + .../themes/twitter/elements/button.overrides | 13 + .../themes/twitter/elements/button.variables | 45 + web/semantic/tasks/README.md | 17 + web/semantic/tasks/admin/components/create.js | 332 + web/semantic/tasks/admin/components/init.js | 170 + web/semantic/tasks/admin/components/update.js | 184 + .../tasks/admin/distributions/create.js | 216 + .../tasks/admin/distributions/init.js | 170 + .../tasks/admin/distributions/update.js | 182 + web/semantic/tasks/admin/publish.js | 25 + web/semantic/tasks/admin/register.js | 55 + web/semantic/tasks/admin/release.js | 29 + web/semantic/tasks/build.js | 137 + web/semantic/tasks/check-install.js | 28 + web/semantic/tasks/clean.js | 14 + web/semantic/tasks/collections/README.md | 16 + web/semantic/tasks/collections/admin.js | 49 + web/semantic/tasks/collections/internal.js | 214 + web/semantic/tasks/config/admin/github.js | 38 + .../tasks/config/admin/oauth.example.js | 10 + web/semantic/tasks/config/admin/release.js | 110 + .../tasks/config/admin/templates/README.md | 29 + .../tasks/config/admin/templates/bower.json | 29 + .../admin/templates/component-package.js | 14 + .../config/admin/templates/composer.json | 20 + .../config/admin/templates/css-package.js | 33 + .../config/admin/templates/less-package.js | 21 + .../tasks/config/admin/templates/package.json | 17 + web/semantic/tasks/config/defaults.js | 116 + web/semantic/tasks/config/docs.js | 24 + web/semantic/tasks/config/npm/gulpfile.js | 59 + web/semantic/tasks/config/project/config.js | 135 + web/semantic/tasks/config/project/install.js | 762 + web/semantic/tasks/config/project/release.js | 61 + web/semantic/tasks/config/project/tasks.js | 127 + web/semantic/tasks/config/user.js | 58 + web/semantic/tasks/docs/build.js | 158 + web/semantic/tasks/docs/serve.js | 236 + web/semantic/tasks/install.js | 391 + web/semantic/tasks/rtl/build.js | 132 + web/semantic/tasks/rtl/watch.js | 221 + web/semantic/tasks/version.js | 11 + web/semantic/tasks/watch.js | 225 + web/semantic/test/fixtures/accordion.html | 24 + web/semantic/test/fixtures/checkbox.html | 46 + web/semantic/test/fixtures/dropdown.html | 9 + web/semantic/test/fixtures/modal.html | 25 + web/semantic/test/fixtures/popup.html | 8 + web/semantic/test/fixtures/rating.html | 7 + web/semantic/test/fixtures/shape.html | 7 + web/semantic/test/fixtures/sidebar.html | 25 + web/semantic/test/fixtures/tab.html | 8 + web/semantic/test/fixtures/transition.html | 1 + web/semantic/test/fixtures/video.html | 5 + web/semantic/test/helpers/jasmine-clog.js | 17 + web/semantic/test/helpers/jasmine-jquery.js | 705 + web/semantic/test/helpers/jasmine-sinon.js | 58 + web/semantic/test/helpers/jquery-events.js | 28 + web/semantic/test/helpers/sinon.js | 4819 +++ web/semantic/test/meteor/assets.js | 20 + web/semantic/test/meteor/fonts.js | 16 + web/semantic/test/modules/accordion.spec.js | 10 + web/semantic/test/modules/checkbox.spec.js | 8 + web/semantic/test/modules/dropdown.spec.js | 8 + web/semantic/test/modules/modal.spec.js | 10 + web/semantic/test/modules/module.spec.js | 218 + web/semantic/test/modules/popup.spec.js | 8 + web/semantic/test/modules/search.spec.js | 8 + web/semantic/test/modules/shape.spec.js | 8 + web/semantic/test/modules/sidebar.spec.js | 8 + web/semantic/test/modules/tab.spec.js | 9 + web/semantic/test/modules/transition.spec.js | 8 + web/semantic/test/modules/video.spec.js | 8 + 621 files changed, 172488 insertions(+), 15939 deletions(-) delete mode 100755 web/css/semantic.min.css delete mode 100755 web/css/semantic.scss create mode 100644 web/semantic/.csscomb.json create mode 100644 web/semantic/.csslintrc create mode 100644 web/semantic/.gitignore create mode 100644 web/semantic/.jshintrc create mode 100644 web/semantic/CONTRIBUTING.md create mode 100644 web/semantic/LICENSE.md create mode 100644 web/semantic/README.md create mode 100644 web/semantic/RELEASE-NOTES.md create mode 100644 web/semantic/bower.json create mode 100644 web/semantic/composer.json create mode 100644 web/semantic/dist/components/accordion.css create mode 100644 web/semantic/dist/components/accordion.js create mode 100644 web/semantic/dist/components/accordion.min.css create mode 100644 web/semantic/dist/components/accordion.min.js create mode 100644 web/semantic/dist/components/ad.css create mode 100644 web/semantic/dist/components/ad.min.css create mode 100644 web/semantic/dist/components/api.js create mode 100644 web/semantic/dist/components/api.min.js create mode 100644 web/semantic/dist/components/breadcrumb.css create mode 100644 web/semantic/dist/components/breadcrumb.min.css create mode 100644 web/semantic/dist/components/button.css create mode 100644 web/semantic/dist/components/button.min.css create mode 100644 web/semantic/dist/components/card.css create mode 100644 web/semantic/dist/components/card.min.css create mode 100644 web/semantic/dist/components/checkbox.css create mode 100644 web/semantic/dist/components/checkbox.js create mode 100644 web/semantic/dist/components/checkbox.min.css create mode 100644 web/semantic/dist/components/checkbox.min.js create mode 100644 web/semantic/dist/components/comment.css create mode 100644 web/semantic/dist/components/comment.min.css create mode 100644 web/semantic/dist/components/dimmer.css create mode 100644 web/semantic/dist/components/dimmer.js create mode 100644 web/semantic/dist/components/dimmer.min.css create mode 100644 web/semantic/dist/components/dimmer.min.js create mode 100644 web/semantic/dist/components/divider.css create mode 100644 web/semantic/dist/components/divider.min.css create mode 100644 web/semantic/dist/components/dropdown.css create mode 100644 web/semantic/dist/components/dropdown.js create mode 100644 web/semantic/dist/components/dropdown.min.css create mode 100644 web/semantic/dist/components/dropdown.min.js create mode 100644 web/semantic/dist/components/feed.css create mode 100644 web/semantic/dist/components/feed.min.css create mode 100644 web/semantic/dist/components/flag.css create mode 100644 web/semantic/dist/components/flag.min.css create mode 100644 web/semantic/dist/components/form.css create mode 100644 web/semantic/dist/components/form.js create mode 100644 web/semantic/dist/components/form.min.css create mode 100644 web/semantic/dist/components/form.min.js create mode 100644 web/semantic/dist/components/grid.css create mode 100644 web/semantic/dist/components/grid.min.css create mode 100644 web/semantic/dist/components/header.css create mode 100644 web/semantic/dist/components/header.min.css create mode 100644 web/semantic/dist/components/icon.css create mode 100644 web/semantic/dist/components/icon.min.css create mode 100644 web/semantic/dist/components/image.css create mode 100644 web/semantic/dist/components/image.min.css create mode 100644 web/semantic/dist/components/input.css create mode 100644 web/semantic/dist/components/input.min.css create mode 100644 web/semantic/dist/components/item.css create mode 100644 web/semantic/dist/components/item.min.css create mode 100644 web/semantic/dist/components/label.css create mode 100644 web/semantic/dist/components/label.min.css create mode 100644 web/semantic/dist/components/list.css create mode 100644 web/semantic/dist/components/list.min.css create mode 100644 web/semantic/dist/components/loader.css create mode 100644 web/semantic/dist/components/loader.min.css create mode 100644 web/semantic/dist/components/menu.css create mode 100644 web/semantic/dist/components/menu.min.css create mode 100644 web/semantic/dist/components/message.css create mode 100644 web/semantic/dist/components/message.min.css create mode 100644 web/semantic/dist/components/modal.css create mode 100644 web/semantic/dist/components/modal.js create mode 100644 web/semantic/dist/components/modal.min.css create mode 100644 web/semantic/dist/components/modal.min.js create mode 100644 web/semantic/dist/components/nag.css create mode 100644 web/semantic/dist/components/nag.js create mode 100644 web/semantic/dist/components/nag.min.css create mode 100644 web/semantic/dist/components/nag.min.js create mode 100644 web/semantic/dist/components/popup.css create mode 100644 web/semantic/dist/components/popup.js create mode 100644 web/semantic/dist/components/popup.min.css create mode 100644 web/semantic/dist/components/popup.min.js create mode 100644 web/semantic/dist/components/progress.css create mode 100644 web/semantic/dist/components/progress.js create mode 100644 web/semantic/dist/components/progress.min.css create mode 100644 web/semantic/dist/components/progress.min.js create mode 100644 web/semantic/dist/components/rail.css create mode 100644 web/semantic/dist/components/rail.min.css create mode 100644 web/semantic/dist/components/rating.css create mode 100644 web/semantic/dist/components/rating.js create mode 100644 web/semantic/dist/components/rating.min.css create mode 100644 web/semantic/dist/components/rating.min.js create mode 100644 web/semantic/dist/components/reset.css create mode 100644 web/semantic/dist/components/reset.min.css create mode 100644 web/semantic/dist/components/reveal.css create mode 100644 web/semantic/dist/components/reveal.min.css create mode 100644 web/semantic/dist/components/search.css create mode 100644 web/semantic/dist/components/search.js create mode 100644 web/semantic/dist/components/search.min.css create mode 100644 web/semantic/dist/components/search.min.js create mode 100644 web/semantic/dist/components/segment.css create mode 100644 web/semantic/dist/components/segment.min.css create mode 100644 web/semantic/dist/components/shape.css create mode 100644 web/semantic/dist/components/shape.js create mode 100644 web/semantic/dist/components/shape.min.css create mode 100644 web/semantic/dist/components/shape.min.js create mode 100644 web/semantic/dist/components/sidebar.css create mode 100644 web/semantic/dist/components/sidebar.js create mode 100644 web/semantic/dist/components/sidebar.min.css create mode 100644 web/semantic/dist/components/sidebar.min.js create mode 100644 web/semantic/dist/components/site.css create mode 100644 web/semantic/dist/components/site.js create mode 100644 web/semantic/dist/components/site.min.css create mode 100644 web/semantic/dist/components/site.min.js create mode 100644 web/semantic/dist/components/state.js create mode 100644 web/semantic/dist/components/state.min.js create mode 100644 web/semantic/dist/components/statistic.css create mode 100644 web/semantic/dist/components/statistic.min.css create mode 100644 web/semantic/dist/components/step.css create mode 100644 web/semantic/dist/components/step.min.css create mode 100644 web/semantic/dist/components/sticky.css create mode 100644 web/semantic/dist/components/sticky.js create mode 100644 web/semantic/dist/components/sticky.min.css create mode 100644 web/semantic/dist/components/sticky.min.js create mode 100644 web/semantic/dist/components/tab.css create mode 100644 web/semantic/dist/components/tab.js create mode 100644 web/semantic/dist/components/tab.min.css create mode 100644 web/semantic/dist/components/tab.min.js create mode 100644 web/semantic/dist/components/table.css create mode 100644 web/semantic/dist/components/table.min.css create mode 100644 web/semantic/dist/components/transition.css create mode 100644 web/semantic/dist/components/transition.js create mode 100644 web/semantic/dist/components/transition.min.css create mode 100644 web/semantic/dist/components/transition.min.js create mode 100644 web/semantic/dist/components/video.css create mode 100644 web/semantic/dist/components/video.js create mode 100644 web/semantic/dist/components/video.min.css create mode 100644 web/semantic/dist/components/video.min.js create mode 100644 web/semantic/dist/components/visibility.js create mode 100644 web/semantic/dist/components/visibility.min.js create mode 100644 web/semantic/dist/semantic.css create mode 100644 web/semantic/dist/semantic.js create mode 100644 web/semantic/dist/semantic.min.css create mode 100644 web/semantic/dist/semantic.min.js create mode 100644 web/semantic/dist/themes/basic/assets/fonts/icons.eot create mode 100644 web/semantic/dist/themes/basic/assets/fonts/icons.svg create mode 100644 web/semantic/dist/themes/basic/assets/fonts/icons.ttf create mode 100644 web/semantic/dist/themes/basic/assets/fonts/icons.woff create mode 100644 web/semantic/dist/themes/default/assets/fonts/icons.eot create mode 100644 web/semantic/dist/themes/default/assets/fonts/icons.otf create mode 100644 web/semantic/dist/themes/default/assets/fonts/icons.svg create mode 100644 web/semantic/dist/themes/default/assets/fonts/icons.ttf create mode 100644 web/semantic/dist/themes/default/assets/fonts/icons.woff create mode 100644 web/semantic/dist/themes/default/assets/fonts/icons.woff2 create mode 100644 web/semantic/dist/themes/default/assets/images/flags.png create mode 100644 web/semantic/examples/feed.css create mode 100644 web/semantic/examples/feed.html create mode 100644 web/semantic/examples/feed.js create mode 100644 web/semantic/examples/grid.css create mode 100644 web/semantic/examples/grid.html create mode 100644 web/semantic/examples/homepage.css create mode 100644 web/semantic/examples/homepage.html create mode 100644 web/semantic/examples/homepage.js create mode 100644 web/semantic/examples/images/bg.jpg create mode 100644 web/semantic/examples/images/cat.png create mode 100644 web/semantic/examples/images/wireframe/centered-paragraph.png create mode 100644 web/semantic/examples/images/wireframe/image-square.png create mode 100644 web/semantic/examples/images/wireframe/image-text.png create mode 100644 web/semantic/examples/images/wireframe/image.png create mode 100644 web/semantic/examples/images/wireframe/media-paragraph-alt.png create mode 100644 web/semantic/examples/images/wireframe/media-paragraph.png create mode 100644 web/semantic/examples/images/wireframe/paragraph.png create mode 100644 web/semantic/examples/images/wireframe/short-paragraph.png create mode 100644 web/semantic/examples/images/wireframe/square-image.png create mode 100644 web/semantic/examples/images/wireframe/text-image.png create mode 100644 web/semantic/examples/images/wireframe/white-image.png create mode 100644 web/semantic/examples/kitchensink.css create mode 100644 web/semantic/examples/kitchensink.html create mode 100644 web/semantic/gulpfile.js create mode 100644 web/semantic/karma.conf.js create mode 100644 web/semantic/logo.png create mode 100644 web/semantic/package.json create mode 100644 web/semantic/semantic.json.example create mode 100644 web/semantic/src/README.md create mode 100644 web/semantic/src/_site/collections/breadcrumb.overrides create mode 100644 web/semantic/src/_site/collections/breadcrumb.variables create mode 100644 web/semantic/src/_site/collections/form.overrides create mode 100644 web/semantic/src/_site/collections/form.variables create mode 100644 web/semantic/src/_site/collections/grid.overrides create mode 100644 web/semantic/src/_site/collections/grid.variables create mode 100644 web/semantic/src/_site/collections/menu.overrides create mode 100644 web/semantic/src/_site/collections/menu.variables create mode 100644 web/semantic/src/_site/collections/message.overrides create mode 100644 web/semantic/src/_site/collections/message.variables create mode 100644 web/semantic/src/_site/collections/table.overrides create mode 100644 web/semantic/src/_site/collections/table.variables create mode 100644 web/semantic/src/_site/elements/button.overrides create mode 100644 web/semantic/src/_site/elements/button.variables create mode 100644 web/semantic/src/_site/elements/divider.overrides create mode 100644 web/semantic/src/_site/elements/divider.variables create mode 100644 web/semantic/src/_site/elements/flag.overrides create mode 100644 web/semantic/src/_site/elements/flag.variables create mode 100644 web/semantic/src/_site/elements/header.overrides create mode 100644 web/semantic/src/_site/elements/header.variables create mode 100644 web/semantic/src/_site/elements/icon.overrides create mode 100644 web/semantic/src/_site/elements/icon.variables create mode 100644 web/semantic/src/_site/elements/image.overrides create mode 100644 web/semantic/src/_site/elements/image.variables create mode 100644 web/semantic/src/_site/elements/input.overrides create mode 100644 web/semantic/src/_site/elements/input.variables create mode 100644 web/semantic/src/_site/elements/label.overrides create mode 100644 web/semantic/src/_site/elements/label.variables create mode 100644 web/semantic/src/_site/elements/list.overrides create mode 100644 web/semantic/src/_site/elements/list.variables create mode 100644 web/semantic/src/_site/elements/loader.overrides create mode 100644 web/semantic/src/_site/elements/loader.variables create mode 100644 web/semantic/src/_site/elements/rail.overrides create mode 100644 web/semantic/src/_site/elements/rail.variables create mode 100644 web/semantic/src/_site/elements/reveal.overrides create mode 100644 web/semantic/src/_site/elements/reveal.variables create mode 100644 web/semantic/src/_site/elements/segment.overrides create mode 100644 web/semantic/src/_site/elements/segment.variables create mode 100644 web/semantic/src/_site/elements/step.overrides create mode 100644 web/semantic/src/_site/elements/step.variables create mode 100644 web/semantic/src/_site/globals/reset.overrides create mode 100644 web/semantic/src/_site/globals/reset.variables create mode 100644 web/semantic/src/_site/globals/site.overrides create mode 100644 web/semantic/src/_site/globals/site.variables create mode 100644 web/semantic/src/_site/modules/accordion.overrides create mode 100644 web/semantic/src/_site/modules/accordion.variables create mode 100644 web/semantic/src/_site/modules/chatroom.overrides create mode 100644 web/semantic/src/_site/modules/chatroom.variables create mode 100644 web/semantic/src/_site/modules/checkbox.overrides create mode 100644 web/semantic/src/_site/modules/checkbox.variables create mode 100644 web/semantic/src/_site/modules/dimmer.overrides create mode 100644 web/semantic/src/_site/modules/dimmer.variables create mode 100644 web/semantic/src/_site/modules/dropdown.overrides create mode 100644 web/semantic/src/_site/modules/dropdown.variables create mode 100644 web/semantic/src/_site/modules/modal.overrides create mode 100644 web/semantic/src/_site/modules/modal.variables create mode 100644 web/semantic/src/_site/modules/nag.overrides create mode 100644 web/semantic/src/_site/modules/nag.variables create mode 100644 web/semantic/src/_site/modules/popup.overrides create mode 100644 web/semantic/src/_site/modules/popup.variables create mode 100644 web/semantic/src/_site/modules/progress.overrides create mode 100644 web/semantic/src/_site/modules/progress.variables create mode 100644 web/semantic/src/_site/modules/rating.overrides create mode 100644 web/semantic/src/_site/modules/rating.variables create mode 100644 web/semantic/src/_site/modules/search.overrides create mode 100644 web/semantic/src/_site/modules/search.variables create mode 100644 web/semantic/src/_site/modules/shape.overrides create mode 100644 web/semantic/src/_site/modules/shape.variables create mode 100644 web/semantic/src/_site/modules/sidebar.overrides create mode 100644 web/semantic/src/_site/modules/sidebar.variables create mode 100644 web/semantic/src/_site/modules/sticky.overrides create mode 100644 web/semantic/src/_site/modules/sticky.variables create mode 100644 web/semantic/src/_site/modules/tab.overrides create mode 100644 web/semantic/src/_site/modules/tab.variables create mode 100644 web/semantic/src/_site/modules/transition.overrides create mode 100644 web/semantic/src/_site/modules/transition.variables create mode 100644 web/semantic/src/_site/modules/video.overrides rename web/{css/custom.scss => semantic/src/_site/modules/video.variables} (100%) create mode 100644 web/semantic/src/_site/views/ad.overrides create mode 100644 web/semantic/src/_site/views/ad.variables create mode 100644 web/semantic/src/_site/views/card.overrides create mode 100644 web/semantic/src/_site/views/card.variables create mode 100644 web/semantic/src/_site/views/comment.overrides create mode 100644 web/semantic/src/_site/views/comment.variables create mode 100644 web/semantic/src/_site/views/feed.overrides create mode 100644 web/semantic/src/_site/views/feed.variables create mode 100644 web/semantic/src/_site/views/item.overrides create mode 100644 web/semantic/src/_site/views/item.variables create mode 100644 web/semantic/src/_site/views/statistic.overrides create mode 100644 web/semantic/src/_site/views/statistic.variables create mode 100644 web/semantic/src/definitions/behaviors/api.js create mode 100644 web/semantic/src/definitions/behaviors/colorize.js create mode 100644 web/semantic/src/definitions/behaviors/form.js create mode 100644 web/semantic/src/definitions/behaviors/state.js create mode 100644 web/semantic/src/definitions/behaviors/visibility.js create mode 100644 web/semantic/src/definitions/behaviors/visit.js create mode 100644 web/semantic/src/definitions/collections/breadcrumb.less create mode 100644 web/semantic/src/definitions/collections/form.less create mode 100644 web/semantic/src/definitions/collections/grid.less create mode 100644 web/semantic/src/definitions/collections/menu.less create mode 100644 web/semantic/src/definitions/collections/message.less create mode 100644 web/semantic/src/definitions/collections/table.less create mode 100644 web/semantic/src/definitions/elements/button.less create mode 100644 web/semantic/src/definitions/elements/divider.less create mode 100644 web/semantic/src/definitions/elements/flag.less create mode 100644 web/semantic/src/definitions/elements/header.less create mode 100644 web/semantic/src/definitions/elements/icon.less create mode 100644 web/semantic/src/definitions/elements/image.less create mode 100644 web/semantic/src/definitions/elements/input.less create mode 100644 web/semantic/src/definitions/elements/label.less create mode 100644 web/semantic/src/definitions/elements/list.less create mode 100644 web/semantic/src/definitions/elements/loader.less create mode 100644 web/semantic/src/definitions/elements/rail.less create mode 100644 web/semantic/src/definitions/elements/reveal.less create mode 100644 web/semantic/src/definitions/elements/segment.less create mode 100644 web/semantic/src/definitions/elements/step.less create mode 100644 web/semantic/src/definitions/globals/reset.less create mode 100644 web/semantic/src/definitions/globals/site.js create mode 100644 web/semantic/src/definitions/globals/site.less create mode 100644 web/semantic/src/definitions/modules/accordion.js create mode 100644 web/semantic/src/definitions/modules/accordion.less create mode 100644 web/semantic/src/definitions/modules/checkbox.js create mode 100644 web/semantic/src/definitions/modules/checkbox.less create mode 100644 web/semantic/src/definitions/modules/dimmer.js create mode 100644 web/semantic/src/definitions/modules/dimmer.less create mode 100644 web/semantic/src/definitions/modules/dropdown.js create mode 100644 web/semantic/src/definitions/modules/dropdown.less create mode 100644 web/semantic/src/definitions/modules/modal.js create mode 100644 web/semantic/src/definitions/modules/modal.less create mode 100644 web/semantic/src/definitions/modules/nag.js create mode 100644 web/semantic/src/definitions/modules/nag.less create mode 100644 web/semantic/src/definitions/modules/popup.js create mode 100644 web/semantic/src/definitions/modules/popup.less create mode 100644 web/semantic/src/definitions/modules/progress.js create mode 100644 web/semantic/src/definitions/modules/progress.less create mode 100644 web/semantic/src/definitions/modules/rating.js create mode 100644 web/semantic/src/definitions/modules/rating.less create mode 100644 web/semantic/src/definitions/modules/search.js create mode 100644 web/semantic/src/definitions/modules/search.less create mode 100644 web/semantic/src/definitions/modules/shape.js create mode 100644 web/semantic/src/definitions/modules/shape.less create mode 100644 web/semantic/src/definitions/modules/sidebar.js create mode 100644 web/semantic/src/definitions/modules/sidebar.less create mode 100644 web/semantic/src/definitions/modules/sticky.js create mode 100644 web/semantic/src/definitions/modules/sticky.less create mode 100644 web/semantic/src/definitions/modules/tab.js create mode 100644 web/semantic/src/definitions/modules/tab.less create mode 100644 web/semantic/src/definitions/modules/transition.js create mode 100644 web/semantic/src/definitions/modules/transition.less create mode 100644 web/semantic/src/definitions/modules/video.js create mode 100644 web/semantic/src/definitions/modules/video.less create mode 100644 web/semantic/src/definitions/views/ad.less create mode 100644 web/semantic/src/definitions/views/card.less create mode 100644 web/semantic/src/definitions/views/comment.less create mode 100644 web/semantic/src/definitions/views/feed.less create mode 100644 web/semantic/src/definitions/views/item.less create mode 100644 web/semantic/src/definitions/views/statistic.less create mode 100644 web/semantic/src/semantic.less create mode 100644 web/semantic/src/theme.config.example create mode 100644 web/semantic/src/theme.less create mode 100644 web/semantic/src/themes/amazon/elements/button.overrides create mode 100644 web/semantic/src/themes/amazon/elements/button.variables create mode 100644 web/semantic/src/themes/basic/assets/fonts/icons.eot create mode 100644 web/semantic/src/themes/basic/assets/fonts/icons.svg create mode 100644 web/semantic/src/themes/basic/assets/fonts/icons.ttf create mode 100644 web/semantic/src/themes/basic/assets/fonts/icons.woff create mode 100644 web/semantic/src/themes/basic/collections/table.overrides create mode 100644 web/semantic/src/themes/basic/collections/table.variables create mode 100644 web/semantic/src/themes/basic/elements/button.overrides create mode 100644 web/semantic/src/themes/basic/elements/button.variables create mode 100644 web/semantic/src/themes/basic/elements/icon.overrides create mode 100644 web/semantic/src/themes/basic/elements/icon.variables create mode 100644 web/semantic/src/themes/basic/elements/step.overrides create mode 100644 web/semantic/src/themes/basic/elements/step.variables create mode 100644 web/semantic/src/themes/basic/globals/reset.overrides create mode 100644 web/semantic/src/themes/basic/globals/reset.variables create mode 100644 web/semantic/src/themes/basic/modules/progress.overrides create mode 100644 web/semantic/src/themes/basic/modules/progress.variables create mode 100644 web/semantic/src/themes/basic/views/card.overrides create mode 100644 web/semantic/src/themes/basic/views/card.variables create mode 100644 web/semantic/src/themes/bookish/elements/header.overrides create mode 100644 web/semantic/src/themes/bookish/elements/header.variables rename web/{css/events.css => semantic/src/themes/bootstrap3/elements/button.overrides} (100%) mode change 100755 => 100644 create mode 100644 web/semantic/src/themes/bootstrap3/elements/button.variables create mode 100644 web/semantic/src/themes/chubby/collections/form.overrides create mode 100644 web/semantic/src/themes/chubby/collections/form.variables create mode 100644 web/semantic/src/themes/chubby/elements/button.overrides create mode 100644 web/semantic/src/themes/chubby/elements/button.variables create mode 100644 web/semantic/src/themes/chubby/elements/header.overrides create mode 100644 web/semantic/src/themes/chubby/elements/header.variables create mode 100644 web/semantic/src/themes/chubby/modules/accordion.overrides create mode 100644 web/semantic/src/themes/chubby/modules/accordion.variables create mode 100644 web/semantic/src/themes/chubby/views/comment.overrides create mode 100644 web/semantic/src/themes/chubby/views/comment.variables create mode 100644 web/semantic/src/themes/classic/collections/table.overrides create mode 100644 web/semantic/src/themes/classic/collections/table.variables create mode 100644 web/semantic/src/themes/classic/elements/button.overrides create mode 100644 web/semantic/src/themes/classic/elements/button.variables create mode 100644 web/semantic/src/themes/classic/elements/header.overrides create mode 100644 web/semantic/src/themes/classic/elements/header.variables create mode 100644 web/semantic/src/themes/classic/modules/progress.overrides create mode 100644 web/semantic/src/themes/classic/modules/progress.variables create mode 100644 web/semantic/src/themes/classic/views/card.overrides create mode 100644 web/semantic/src/themes/classic/views/card.variables create mode 100644 web/semantic/src/themes/default/assets/fonts/icons.eot create mode 100644 web/semantic/src/themes/default/assets/fonts/icons.svg create mode 100644 web/semantic/src/themes/default/assets/fonts/icons.ttf create mode 100644 web/semantic/src/themes/default/assets/fonts/icons.woff create mode 100644 web/semantic/src/themes/default/assets/fonts/icons.woff2 create mode 100644 web/semantic/src/themes/default/assets/images/flags.png create mode 100644 web/semantic/src/themes/default/collections/breadcrumb.overrides create mode 100644 web/semantic/src/themes/default/collections/breadcrumb.variables create mode 100644 web/semantic/src/themes/default/collections/form.overrides create mode 100644 web/semantic/src/themes/default/collections/form.variables create mode 100644 web/semantic/src/themes/default/collections/grid.overrides create mode 100644 web/semantic/src/themes/default/collections/grid.variables create mode 100644 web/semantic/src/themes/default/collections/menu.overrides create mode 100644 web/semantic/src/themes/default/collections/menu.variables create mode 100644 web/semantic/src/themes/default/collections/message.overrides create mode 100644 web/semantic/src/themes/default/collections/message.variables create mode 100644 web/semantic/src/themes/default/collections/table.overrides create mode 100644 web/semantic/src/themes/default/collections/table.variables create mode 100644 web/semantic/src/themes/default/elements/button.overrides create mode 100644 web/semantic/src/themes/default/elements/button.variables create mode 100644 web/semantic/src/themes/default/elements/divider.overrides create mode 100644 web/semantic/src/themes/default/elements/divider.variables create mode 100644 web/semantic/src/themes/default/elements/flag.overrides create mode 100644 web/semantic/src/themes/default/elements/flag.variables create mode 100644 web/semantic/src/themes/default/elements/header.overrides create mode 100644 web/semantic/src/themes/default/elements/header.variables create mode 100644 web/semantic/src/themes/default/elements/icon.overrides create mode 100644 web/semantic/src/themes/default/elements/icon.variables create mode 100644 web/semantic/src/themes/default/elements/image.overrides create mode 100644 web/semantic/src/themes/default/elements/image.variables create mode 100644 web/semantic/src/themes/default/elements/input.overrides create mode 100644 web/semantic/src/themes/default/elements/input.variables create mode 100644 web/semantic/src/themes/default/elements/label.overrides create mode 100644 web/semantic/src/themes/default/elements/label.variables create mode 100644 web/semantic/src/themes/default/elements/list.overrides create mode 100644 web/semantic/src/themes/default/elements/list.variables create mode 100644 web/semantic/src/themes/default/elements/loader.overrides create mode 100644 web/semantic/src/themes/default/elements/loader.variables create mode 100644 web/semantic/src/themes/default/elements/rail.overrides create mode 100644 web/semantic/src/themes/default/elements/rail.variables create mode 100644 web/semantic/src/themes/default/elements/reveal.overrides create mode 100644 web/semantic/src/themes/default/elements/reveal.variables create mode 100644 web/semantic/src/themes/default/elements/segment.overrides create mode 100644 web/semantic/src/themes/default/elements/segment.variables create mode 100644 web/semantic/src/themes/default/elements/step.overrides create mode 100644 web/semantic/src/themes/default/elements/step.variables create mode 100644 web/semantic/src/themes/default/globals/reset.overrides create mode 100644 web/semantic/src/themes/default/globals/reset.variables create mode 100644 web/semantic/src/themes/default/globals/site.overrides create mode 100644 web/semantic/src/themes/default/globals/site.variables create mode 100644 web/semantic/src/themes/default/modules/accordion.overrides create mode 100644 web/semantic/src/themes/default/modules/accordion.variables create mode 100644 web/semantic/src/themes/default/modules/chatroom.overrides create mode 100644 web/semantic/src/themes/default/modules/chatroom.variables create mode 100644 web/semantic/src/themes/default/modules/checkbox.overrides create mode 100644 web/semantic/src/themes/default/modules/checkbox.variables create mode 100644 web/semantic/src/themes/default/modules/dimmer.overrides create mode 100644 web/semantic/src/themes/default/modules/dimmer.variables create mode 100644 web/semantic/src/themes/default/modules/dropdown.overrides create mode 100644 web/semantic/src/themes/default/modules/dropdown.variables create mode 100644 web/semantic/src/themes/default/modules/modal.overrides create mode 100644 web/semantic/src/themes/default/modules/modal.variables create mode 100644 web/semantic/src/themes/default/modules/nag.overrides create mode 100644 web/semantic/src/themes/default/modules/nag.variables create mode 100644 web/semantic/src/themes/default/modules/popup.overrides create mode 100644 web/semantic/src/themes/default/modules/popup.variables create mode 100644 web/semantic/src/themes/default/modules/progress.overrides create mode 100644 web/semantic/src/themes/default/modules/progress.variables create mode 100644 web/semantic/src/themes/default/modules/rating.overrides create mode 100644 web/semantic/src/themes/default/modules/rating.variables create mode 100644 web/semantic/src/themes/default/modules/search.overrides create mode 100644 web/semantic/src/themes/default/modules/search.variables create mode 100644 web/semantic/src/themes/default/modules/shape.overrides create mode 100644 web/semantic/src/themes/default/modules/shape.variables create mode 100644 web/semantic/src/themes/default/modules/sidebar.overrides create mode 100644 web/semantic/src/themes/default/modules/sidebar.variables create mode 100644 web/semantic/src/themes/default/modules/sticky.overrides create mode 100644 web/semantic/src/themes/default/modules/sticky.variables create mode 100644 web/semantic/src/themes/default/modules/tab.overrides create mode 100644 web/semantic/src/themes/default/modules/tab.variables create mode 100644 web/semantic/src/themes/default/modules/transition.overrides create mode 100644 web/semantic/src/themes/default/modules/transition.variables create mode 100644 web/semantic/src/themes/default/modules/video.overrides create mode 100644 web/semantic/src/themes/default/modules/video.variables create mode 100644 web/semantic/src/themes/default/views/ad.overrides create mode 100644 web/semantic/src/themes/default/views/ad.variables create mode 100644 web/semantic/src/themes/default/views/card.overrides create mode 100644 web/semantic/src/themes/default/views/card.variables create mode 100644 web/semantic/src/themes/default/views/comment.overrides create mode 100644 web/semantic/src/themes/default/views/comment.variables create mode 100644 web/semantic/src/themes/default/views/feed.overrides create mode 100644 web/semantic/src/themes/default/views/feed.variables create mode 100644 web/semantic/src/themes/default/views/item.overrides create mode 100644 web/semantic/src/themes/default/views/item.variables create mode 100644 web/semantic/src/themes/default/views/statistic.overrides create mode 100644 web/semantic/src/themes/default/views/statistic.variables create mode 100644 web/semantic/src/themes/duo/elements/loader.overrides create mode 100644 web/semantic/src/themes/duo/elements/loader.variables create mode 100644 web/semantic/src/themes/fixed-width/collections/grid.overrides create mode 100644 web/semantic/src/themes/fixed-width/collections/grid.variables create mode 100644 web/semantic/src/themes/fixed-width/modules/modal.overrides create mode 100644 web/semantic/src/themes/fixed-width/modules/modal.variables create mode 100644 web/semantic/src/themes/flat/collections/form.overrides create mode 100644 web/semantic/src/themes/flat/collections/form.variables create mode 100644 web/semantic/src/themes/flat/globals/site.overrides create mode 100644 web/semantic/src/themes/flat/globals/site.variables create mode 100644 web/semantic/src/themes/github/collections/form.overrides create mode 100644 web/semantic/src/themes/github/collections/form.variables create mode 100644 web/semantic/src/themes/github/collections/menu.overrides create mode 100644 web/semantic/src/themes/github/collections/menu.variables create mode 100644 web/semantic/src/themes/github/collections/message.overrides create mode 100644 web/semantic/src/themes/github/collections/message.variables create mode 100644 web/semantic/src/themes/github/elements/button.overrides create mode 100644 web/semantic/src/themes/github/elements/button.variables create mode 100644 web/semantic/src/themes/github/elements/segment.overrides create mode 100644 web/semantic/src/themes/github/elements/segment.variables create mode 100644 web/semantic/src/themes/github/elements/step.overrides create mode 100644 web/semantic/src/themes/github/elements/step.variables create mode 100644 web/semantic/src/themes/gmail/collections/message.overrides create mode 100644 web/semantic/src/themes/gmail/collections/message.variables create mode 100644 web/semantic/src/themes/material/elements/button.overrides create mode 100644 web/semantic/src/themes/material/elements/button.variables create mode 100644 web/semantic/src/themes/material/elements/header.overrides create mode 100644 web/semantic/src/themes/material/elements/header.variables create mode 100644 web/semantic/src/themes/material/globals/site.overrides create mode 100644 web/semantic/src/themes/material/globals/site.variables create mode 100644 web/semantic/src/themes/material/modules/modal.overrides create mode 100644 web/semantic/src/themes/material/modules/modal.variables create mode 100644 web/semantic/src/themes/pulsar/elements/loader.overrides create mode 100644 web/semantic/src/themes/pulsar/elements/loader.variables create mode 100644 web/semantic/src/themes/raised/elements/button.overrides create mode 100644 web/semantic/src/themes/raised/elements/button.variables create mode 100644 web/semantic/src/themes/resetcss/globals/reset.overrides create mode 100644 web/semantic/src/themes/resetcss/globals/reset.variables create mode 100644 web/semantic/src/themes/round/elements/button.overrides create mode 100644 web/semantic/src/themes/round/elements/button.variables create mode 100644 web/semantic/src/themes/rtl/globals/site.overrides create mode 100644 web/semantic/src/themes/rtl/globals/site.variables create mode 100644 web/semantic/src/themes/striped/modules/progress.overrides create mode 100644 web/semantic/src/themes/striped/modules/progress.variables create mode 100644 web/semantic/src/themes/timeline/views/feed.overrides create mode 100644 web/semantic/src/themes/timeline/views/feed.variables create mode 100644 web/semantic/src/themes/twitter/elements/button.overrides create mode 100644 web/semantic/src/themes/twitter/elements/button.variables create mode 100644 web/semantic/tasks/README.md create mode 100644 web/semantic/tasks/admin/components/create.js create mode 100644 web/semantic/tasks/admin/components/init.js create mode 100644 web/semantic/tasks/admin/components/update.js create mode 100644 web/semantic/tasks/admin/distributions/create.js create mode 100644 web/semantic/tasks/admin/distributions/init.js create mode 100644 web/semantic/tasks/admin/distributions/update.js create mode 100644 web/semantic/tasks/admin/publish.js create mode 100644 web/semantic/tasks/admin/register.js create mode 100644 web/semantic/tasks/admin/release.js create mode 100644 web/semantic/tasks/build.js create mode 100644 web/semantic/tasks/check-install.js create mode 100644 web/semantic/tasks/clean.js create mode 100644 web/semantic/tasks/collections/README.md create mode 100644 web/semantic/tasks/collections/admin.js create mode 100644 web/semantic/tasks/collections/internal.js create mode 100644 web/semantic/tasks/config/admin/github.js create mode 100644 web/semantic/tasks/config/admin/oauth.example.js create mode 100644 web/semantic/tasks/config/admin/release.js create mode 100644 web/semantic/tasks/config/admin/templates/README.md create mode 100644 web/semantic/tasks/config/admin/templates/bower.json create mode 100644 web/semantic/tasks/config/admin/templates/component-package.js create mode 100644 web/semantic/tasks/config/admin/templates/composer.json create mode 100644 web/semantic/tasks/config/admin/templates/css-package.js create mode 100644 web/semantic/tasks/config/admin/templates/less-package.js create mode 100644 web/semantic/tasks/config/admin/templates/package.json create mode 100644 web/semantic/tasks/config/defaults.js create mode 100644 web/semantic/tasks/config/docs.js create mode 100644 web/semantic/tasks/config/npm/gulpfile.js create mode 100644 web/semantic/tasks/config/project/config.js create mode 100644 web/semantic/tasks/config/project/install.js create mode 100644 web/semantic/tasks/config/project/release.js create mode 100644 web/semantic/tasks/config/project/tasks.js create mode 100644 web/semantic/tasks/config/user.js create mode 100644 web/semantic/tasks/docs/build.js create mode 100644 web/semantic/tasks/docs/serve.js create mode 100644 web/semantic/tasks/install.js create mode 100644 web/semantic/tasks/rtl/build.js create mode 100644 web/semantic/tasks/rtl/watch.js create mode 100644 web/semantic/tasks/version.js create mode 100644 web/semantic/tasks/watch.js create mode 100644 web/semantic/test/fixtures/accordion.html create mode 100644 web/semantic/test/fixtures/checkbox.html create mode 100644 web/semantic/test/fixtures/dropdown.html create mode 100644 web/semantic/test/fixtures/modal.html create mode 100644 web/semantic/test/fixtures/popup.html create mode 100644 web/semantic/test/fixtures/rating.html create mode 100644 web/semantic/test/fixtures/shape.html create mode 100644 web/semantic/test/fixtures/sidebar.html create mode 100644 web/semantic/test/fixtures/tab.html create mode 100644 web/semantic/test/fixtures/transition.html create mode 100644 web/semantic/test/fixtures/video.html create mode 100644 web/semantic/test/helpers/jasmine-clog.js create mode 100644 web/semantic/test/helpers/jasmine-jquery.js create mode 100644 web/semantic/test/helpers/jasmine-sinon.js create mode 100644 web/semantic/test/helpers/jquery-events.js create mode 100644 web/semantic/test/helpers/sinon.js create mode 100644 web/semantic/test/meteor/assets.js create mode 100644 web/semantic/test/meteor/fonts.js create mode 100644 web/semantic/test/modules/accordion.spec.js create mode 100644 web/semantic/test/modules/checkbox.spec.js create mode 100644 web/semantic/test/modules/dropdown.spec.js create mode 100644 web/semantic/test/modules/modal.spec.js create mode 100644 web/semantic/test/modules/module.spec.js create mode 100644 web/semantic/test/modules/popup.spec.js create mode 100644 web/semantic/test/modules/search.spec.js create mode 100644 web/semantic/test/modules/shape.spec.js create mode 100644 web/semantic/test/modules/sidebar.spec.js create mode 100644 web/semantic/test/modules/tab.spec.js create mode 100644 web/semantic/test/modules/transition.spec.js create mode 100644 web/semantic/test/modules/video.spec.js diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss index 7e0730a..3c230c4 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss @@ -1,3 +1,18 @@ +.card { + h2 { + margin-bottom: 0.3em !important; + a { + color: inherit; + } + } + .meta { + .label,.button { + margin-bottom: 0.3em; + margin-top: 0.3em; + } + } +} + .event.box { h2 { padding: 0.5rem; diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss index b4dd9dd..add0555 100644 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss @@ -1,6 +1,5 @@ body { - margin: 0; - font-family: 'Roboto', sans-serif; + margin: 40px 0 0; } header { diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/events.js b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/events.js index c4dddbd..64698a7 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/events.js +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/events.js @@ -49,7 +49,6 @@ jQuery(document).ready(function () { if (!(jQuery('input[name=location_lat]').val() == undefined)) { jQuery('input[name=location_lat]').val(coords.lat); jQuery('input[name=location_lon]').val(coords.lng); - jQuery('input[name=location]').css('margin-bottom', '3.2rem'); jQuery('span.coords').text('Folgende Koordinaten sind angegeben: lat:' + coords.lat + ', lon:' + coords.lng); } else { jQuery('input[name=geocords]').val(coords.lat + ',' + coords.lng); @@ -83,9 +82,35 @@ jQuery(document).ready(function () { } }); -$(document).ready(function() { +function calcBoxSize(columns) { + var card_selector = jQuery('.ui.cards .card'); + var screen_width = $(window).width() - 14 - 14; /* padding of basic segment */ + // first check if we can display 4 cards on the screen with a minimum width of 399px + var box_width = Math.floor((screen_width / columns)) - 10; + if ((box_width >= 395) || (columns == 1)) { + card_selector.css('width',box_width); + } else { + calcBoxSize(columns - 1); + } +} - if (jQuery('#view-map').length == 1) { +$(window).resize(function(){ + var card_selector = jQuery('.ui.cards .card'); + + if (card_selector.length > 0) { + calcBoxSize(4); + } +}); + +$(document).ready(function() { + var view_map_selector = jQuery('#view-map'); + var card_selector = jQuery('.ui.cards .card'); + + if (card_selector.length > 0) { + calcBoxSize(4); + } + + if (view_map_selector.length == 1) { jQuery('.show_map').click(addGeoCoordinates); map = L.map('view-map'); @@ -108,8 +133,8 @@ $(document).ready(function() { }, onVisible: function () { map.invalidateSize(true); - var lat = $('#view-map').data('lat'); - var lon = $('#view-map').data('lon'); + var lat = view_map_selector.data('lat'); + var lon = view_map_selector.data('lon'); if ((lat > 0) && (lon > 0)) { map.setView([lat, lon], 16); var latlng = new L.LatLng(lat, lon); diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/edit.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/edit.html.twig index a004f41..f712722 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/edit.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/edit.html.twig @@ -19,14 +19,12 @@ {% endblock %} {% block body -%} -
-
-

Termin bearbeiten

-
+
+

Termin bearbeiten

-
-
+
+
{{ include('CalciferBundle:Event:event_form.html.twig',{'entity':entity}) }}
diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_box.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_box.html.twig index 4a9b99a..948a40f 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_box.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_box.html.twig @@ -1,57 +1,61 @@ -
-
-

+
+

{{ entity.summary }}

+
+
+ {{ entity.getFormatedDate() }} +
+ + {% if entity.location is not null %} + + {{ entity.location.name }} + + {% endif %} + + {% if (detail|default(false)) %} + {% if entity.tags|length > 0 %} + {% for tag in entity.tags %} + + {{ tag.name }} + + {% endfor %} + {% endif %} + {% endif %} + + {% if entity.url|length > 0 %} + + {{ entity.url|truncate(30) }} + + {% endif %} +
+ +
+ {% if truncate_summary|default(false) %} +

{{ entity.description|truncate(255)|markdown }}

+ {% else %} +

{{ entity.description|markdown }}

+ {% endif %} +
{% if (detail|default(false)) %} -

- Bearbeiten -

- -

- Löschen -

- -

- Kopieren -

- {% endif %} - -

- {{ entity.getFormatedDate() }} -

- - {% if entity.location is not null %} -

- {{ entity.location.name }} -

- {% endif %} - {% if entity.tags|length > 0 %} - - {% endif %} - - {% if entity.url|length > 0 %} -

- {{ entity.url }} -

- {% endif %} - -
- - {% if truncate_summary|default(false) %} -

{{ entity.description|truncate(255)|markdown }}

- {% else %} -

{{ entity.description|markdown }}

+ + + Bearbeiten + + + + Löschen + + + + Kopieren + {% endif %}

\ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_form.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_form.html.twig index 39ac995..38a4e70 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_form.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/event_form.html.twig @@ -1,142 +1,148 @@ - -
-
- + +
+ -
- - {% if(errors|default('0') != 0) %} {% if('startdate' in errors|keys) %} +
+ + {% if(errors|default('0') != 0) %} {% if('startdate' in errors|keys) %}
{{ errors.startdate }}
- {% endif %}{% endif %} + {% endif %}{% endif %} - - -
- -
-
+
-
- - -
- - - {% if(errors|default('0') != 0) %} {% if('enddate' in errors|keys) %} -
{{ errors.enddate }}
- {% endif %}{% endif %} - - -
+
+ Bitte gebe das Startdatum im Format ISO 8601 an.
-
- +
+
+ -
- +
+ - {% if(errors|default('0') != 0) %} {% if('summary' in errors|keys) %} -
{{ errors.summary }}
- {% endif %}{% endif %} + {% if(errors|default('0') != 0) %} {% if('enddate' in errors|keys) %} +
{{ errors.enddate }}
+ {% endif %}{% endif %} -
- -
-
+
- -
- - -
- -
Du kannst hier Markdown benutzen.
-
+
+ Bitte gebe das Enddatum im Format ISO 8601 an.
+
+
+ -
- +
+ -
- - -
+ {% if(errors|default('0') != 0) %} {% if('summary' in errors|keys) %} +
{{ errors.summary }}
+ {% endif %}{% endif %}
- -
- - -
- - - - -
- Du kannst zu diesem Ort auch Geokoordinaten hinterlegen.
- {% if entity.location.lat|default(0) > 0 %}Folgende Koordinaten sind angegeben: lat:{{ entity.location.lat }}, lon:{{ entity.location.lon }}{% endif %} -
- -
-
- -
- - -
- - -
Du kannst hier kommasepariert Tags angeben.
-
-
- -
+
+ + +
+ +
+
Du kannst hier Markdown + benutzen. +
+
+ +
+ + +
+ + +
+ +
+ Vergesse nicht das https:// zur URL anzugeben. +
+
+ +
+ + +
+ + + + +
+ +
+ Du kannst zu diesem Ort auch Geokoordinaten hinterlegen (JavaScript erforderlich).
+ {% if entity.location.lat|default(0) > 0 %}Folgende Koordinaten sind angegeben: lat:{{ entity.location.lat }}, lon:{{ entity.location.lon }}{% endif %} +
+ +
+ +
+ + +
+ + +
+
Du kannst hier kommasepariert Tags angeben. +
+
+ + \ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig index 457520b..588ffed 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/index.html.twig @@ -2,92 +2,98 @@ {% block css %} {% stylesheets filter="compass" - "@CalciferBundle/Resources/assets/css/events.scss" - "@CalciferBundle/Resources/assets/css/leaflet.scss" - %} - + "@CalciferBundle/Resources/assets/css/events.scss" + "@CalciferBundle/Resources/assets/css/leaflet.scss" %} + {% endstylesheets %} {% endblock %} {% block javascripts %} {% javascripts "@CalciferBundle/Resources/assets/js/events.js" - "@CalciferBundle/Resources/assets/js/leaflet.js" - %} + "@CalciferBundle/Resources/assets/js/leaflet.js" %} {% endjavascripts %} {% endblock %} {% block body -%} -
-
-

- Termine - {% if tags|default(false) %} - {% if tags|length == 1 %} - für Tag {{ tags[0].name }} - {% elseif(tags|length == 2) %} - für die Tags {{ tags[0].name }} {% if operator == 'or' %}oder{% else %}und{% endif %} {{ tags[1].name }} - {% else %} - für die Tags - {% for tag in tags %} - {% if not loop.last %} - {{ tag.name }}{% if loop.index < (tags|length - 1) %},{% endif %} - {% else %} - {% if operator == 'or' %}oder{% else %}und{% endif %} {{ tag.name }} - {% endif %} - {% endfor %} - {% endif %} +
+

+ Termine + {% if tags|default(false) %} + {% if tags|length == 1 %} + für Tag {{ tags[0].name }} + {% elseif(tags|length == 2) %} + für die Tags {{ tags[0].name }} {% if operator == 'or' %}oder{% else %}und{% endif %} {{ tags[1].name }} + {% else %} + für die Tags + {% for tag in tags %} + {% if not loop.last %} + {{ tag.name }}{% if loop.index < (tags|length - 1) %},{% endif %} + {% else %} + {% if operator == 'or' %}oder{% else %}und{% endif %} {{ tag.name }} + {% endif %} + {% endfor %} {% endif %} - {% if location|default(false) %} für Ort „{{ location.name }}“ {% endif %} -

- {% if tag|default(false) %} - Link zur Kalenderdatei {% endif %} - {% if location|default(false) %} - {% if (location.description|length > 0) or location.hasAddress() %} -
- {% if (location.description|length > 0) %} -

{{ location.description|markdown }}

- {% endif %} - {% if (location.hasAddress()) %} -
-

- Anschrift:
- {{ location.streetaddress }}{% if(location.streetnumber|length > 0) %} {{ location.streetnumber }}{% endif %}
+ {% if location|default(false) %} für Ort „{{ location.name }}“ {% endif %} +

+ {% if tag|default(false) %} + Link zur + Kalenderdatei + {% endif %} + {% if location|default(false) %} + {% if (location.description|length > 0) or location.hasAddress() %} +
+ {% if (location.description|length > 0) %} +

{{ location.description|markdown }}

+ {% endif %} + {% if (location.hasAddress()) %} +
+

+ Anschrift:
+ {{ location.streetaddress }}{% if(location.streetnumber|length > 0) %} {{ location.streetnumber }}{% endif %} +
+ {% if(location.zipcode|length > 0) %}{{ location.zipcode }} {% endif %}{{ location.city }} +

+ {% endif %} + {% if ((location.lon > 0) and (location.lat > 0)) %} +

Auf einer OpenStreetMap-Karte anzeigen

+ {% endif %} -
+ {% endif %}
{% if entities|length > 0 %} -
- {% for entity in entities %} - {{ include('CalciferBundle:Event:event_box.html.twig',{'truncate_summary':true}) }} - {% endfor %} +
+
+ {% for entity in entities %} + {{ include('CalciferBundle:Event:event_box.html.twig',{'truncate_summary':true}) }} + {% endfor %} +
{% else %}
diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/show.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/show.html.twig index 7d19293..592eecf 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/show.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/show.html.twig @@ -17,7 +17,7 @@ {% endblock %} {% block body -%} -
+
{{ include('CalciferBundle:Event:event_box.html.twig',{'entity' : entity,'detail' : true}) }}
{% endblock %} diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig index 5142616..130cb69 100644 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Location/edit.html.twig @@ -19,157 +19,151 @@ {% endblock %} {% block body -%} -
-
-

Ort bearbeiten

-
+
+

Ort bearbeiten

-
-
-
+
+ {% set errors = app.session.flashbag.get('error') %} {% if errors|length > 0 %} -
-
Bitte korrigiere folgende Fehler:
-
    - {% for flashMessage in errors %} -
  • {{ flashMessage }}
  • - {% endfor %} -
-
+
+
Bitte korrigiere folgende Fehler:
+
    + {% for flashMessage in errors %} +
  • {{ flashMessage }}
  • + {% endfor %} +
+
{% endif %} -
-
- +
+ -
- - -
- -
-
+
+
- -
- - -
- - -
Du kannst hier Markdown benutzen. -
-
-
- -
- - -
- - -
-
- -
- - -
- - -
-
- -
- - -
- - -
-
- -
- - -
- - -
-
- -
- - -
- - -
- Gebe entweder Breitengrad und Längengrad (Mit Punkten!) kommasepariert ein oder wähle einen Punkt auf der Karte aus. -
- -
-
- - - -
+
+ + +
+ +
+ +
Du kannst hier Markdown benutzen. +
+
+ +
+ + +
+ + +
+
+ +
+ + +
+ + +
+
+ +
+ + +
+ + +
+
+ +
+ + +
+ + +
+
+ +
+ + +
+ + +
+ +
+ Gebe entweder Breitengrad und Längengrad (Mit Punkten!) kommasepariert ein oder wähle + einen Punkt auf der Karte aus. +
+ +
+ + + +
diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/edit.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/edit.html.twig index 25f2f34..84ac09d 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/edit.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/edit.html.twig @@ -4,8 +4,7 @@ {% stylesheets filter="compass" "@CalciferBundle/Resources/assets/css/jquery.datetimepicker.scss" "@CalciferBundle/Resources/assets/css/events.scss" - "@CalciferBundle/Resources/assets/css/leaflet.scss" - %} + "@CalciferBundle/Resources/assets/css/leaflet.scss" %} {% endstylesheets %} {% endblock %} @@ -15,21 +14,18 @@ "@CalciferBundle/Resources/assets/js/jquery.datetimepicker.js" "@CalciferBundle/Resources/assets/js/repeating_events.js" "@CalciferBundle/Resources/assets/js/events.js" - "@CalciferBundle/Resources/assets/js/leaflet.js" - %} + "@CalciferBundle/Resources/assets/js/leaflet.js" %} {% endjavascripts %} {% endblock %} {% block body -%} -
-
-

Wiederholenden Termin bearbeiten

-
+
+

Wiederholenden Termin bearbeiten

-
-
+
+
{{ include('CalciferBundle:RepeatingEvent:repeating_event_form.html.twig',{'entity':entity}) }}
diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/index.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/index.html.twig index 12664f7..c705fdc 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/index.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/index.html.twig @@ -15,51 +15,47 @@ {% endblock %} {% block body -%} -
-
-

- Wiederholende Termine -

-
+
+

+ Wiederholende Termine +

-
-
- - +
+
+ + + + + + + + + + {% for entity in entities %} - - - - + + + + - - - {% for entity in entities %} - - - - - - - {% endfor %} - - - - - - -
ZusammenfassungNächstes DatumWiederholungsmusterAktionen
ZusammenfassungNächstes DatumWiederholungsmusterAktionen + {{ entity.summary }} + + {{ entity.nextdate.format('Y-m-d H:i') }} + + {{ entity.repeating_pattern }} + + Bearbeiten | + Löschen +
- {{ entity.summary }} - - {{ entity.nextdate.format('Y-m-d H:i') }} - - {{ entity.repeating_pattern }} - - Bearbeiten | - Löschen -
Neuen wiederholenden Termin anlegen
-
+ {% endfor %} + + + + Neuen wiederholenden Termin anlegen + + +
diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/new.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/new.html.twig index 22b9509..cb28b39 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/new.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/new.html.twig @@ -20,14 +20,12 @@ {% endblock %} {% block body -%} -
-
-

Wiederholenden Termin erstellen

-
+
+

Wiederholenden Termin erstellen

-
-
+
+
{{ include('CalciferBundle:RepeatingEvent:repeating_event_form.html.twig') }}
diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/repeating_event_form.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/repeating_event_form.html.twig index c532246..0bd20f3 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/repeating_event_form.html.twig +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/RepeatingEvent/repeating_event_form.html.twig @@ -1,10 +1,9 @@ -
-
-
- +
+ -
+
-
- -
+
+ +
+ Bitte gebe das Datum des nächsten Termin im Format ISO 8601 an.
- + -
+
-
- Hier gibst du bitte die Dauer der Veranstaltung in Minuten an. -
+
+
+ Hier gibst du bitte die Dauer der Veranstaltung in Minuten an.
-
- +
+ -
+
+
-
- -
- -
- Gebe hier ein Wiederholungsmuster an. -
+
+ Gebe hier ein Wiederholungsmuster an.
-
- +
+ -
+
- -
- -
- + -
+
- -
Du kannst hier Markdown - benutzen. -
+
+
Du kannst hier Markdown + benutzen.
- + -
+
-
+
-
+
+
-
- Du kannst zu diesem Ort auch Geokoordinaten hinterlegen.
- {% if entity.location.lat|default(0) > 0 %}Folgende Koordinaten sind angegeben: lat:{{ entity.location.lat }}, lon:{{ entity.location.lon }}{% endif %} +
+ Du kannst zu diesem Ort auch Geokoordinaten hinterlegen (JavaScript erforderlich).
+ {% if entity.location.lat|default(0) > 0 %}Folgende Koordinaten sind angegeben: lat:{{ entity.location.lat }}, lon:{{ entity.location.lon }}{% endif %} +
+