diff --git a/INSTALL.md b/INSTALL.md index d213aec..bff3671 100755 --- a/INSTALL.md +++ b/INSTALL.md @@ -10,9 +10,16 @@ Diese Anleitung geht davon aus das du SSH-Zugriff auf deinen Server hast. Wenn du Calcifer auf einem Shared-Hosting-Anbieter installieren willst, so ist dies auch möglich, aber etwas komplizierter und wird irgendwann später beschrieben. - 1. Das [Repo](https://phablab.krautspace.de/diffusion/C/calcifer.git) irgendwo hin clonen - 2. In das calcifer Verzeichnis wechseln. - 3. composer install - 4. Im Verzeichnis app/config die Datei parameters.yml.dist nach parameters.yml kopieren und anpassen. - 5. Dann die Tabellen erstellen: php app/console doctrine:schema:create - 6. Zum Schluss must du noch deinen Webserver [konfigurieren](http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html) und dann ist calcifer auch schon erreichbar. \ No newline at end of file +1. Das [Repo](https://phablab.krautspace.de/diffusion/C/calcifer.git) irgendwo hin clonen +2. In das calcifer Verzeichnis wechseln. +3. Abhängigkeiten installieren + 1. composer herunterladen ```curl -sS https://getcomposer.org/installer | php``` + 2. Installation ausführen: ```php composer.phar install``` + - für PostgreSQL wähl pdo_pgsql als Datenbanktreiber + - für MySQL wähle pdo_mysql als Datenbanktreiber + - für SQLite ist pdo_sqlite zu nutzen, dabei ist der Pfad anzugeben. Der Standardpfad legt die Datei calcifer.sqlite3 im Verzeichnis app an. +5. Dann die Tabellen erstellen: ```php app/console doctrine:schema:update --force``` +6. Cache löschen ```php app/console cache:clear --env=prod --no-debug``` +7. Assets dumpen ```php app/console assetic:dump --env=prod --no-debug``` +8. Einen täglichen Cronjob anlegen, der die wiederholenden Termine anlegt: ```php app/console calcifer:events:generate``` +6. Zum Schluss must du noch deinen Webserver [konfigurieren](http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html) und dann ist calcifer auch schon erreichbar. diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php index ed00a6f..25bc938 100644 --- a/app/SymfonyRequirements.php +++ b/app/SymfonyRequirements.php @@ -602,6 +602,12 @@ class SymfonyRequirements extends RequirementCollection 'Install and enable the XML extension.' ); + $this->addRecommendation( + function_exists('filter_var'), + 'filter_var() should be available', + 'Install and enable the filter extension.' + ); + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { $this->addRecommendation( function_exists('posix_isatty'), @@ -662,7 +668,7 @@ class SymfonyRequirements extends RequirementCollection $this->addRecommendation( $accelerator, 'a PHP accelerator should be installed', - 'Install and enable a PHP accelerator like APC (highly recommended).' + 'Install and/or enable a PHP accelerator (highly recommended).' ); if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { diff --git a/app/check.php b/app/check.php index 91b826b..bb0a20e 100644 --- a/app/check.php +++ b/app/check.php @@ -2,61 +2,141 @@ require_once dirname(__FILE__).'/SymfonyRequirements.php'; +$lineSize = 70; $symfonyRequirements = new SymfonyRequirements(); - $iniPath = $symfonyRequirements->getPhpIniConfigPath(); -echo "********************************\n"; -echo "* *\n"; -echo "* Symfony requirements check *\n"; -echo "* *\n"; -echo "********************************\n\n"; +echo_title('Symfony2 Requirements Checker'); -echo $iniPath ? sprintf("* Configuration file used by PHP: %s\n\n", $iniPath) : "* WARNING: No configuration file (php.ini) used by PHP!\n\n"; - -echo "** ATTENTION **\n"; -echo "* The PHP CLI can use a different php.ini file\n"; -echo "* than the one used with your web server.\n"; -if ('\\' == DIRECTORY_SEPARATOR) { - echo "* (especially on the Windows platform)\n"; +echo '> PHP is using the following php.ini file:'.PHP_EOL; +if ($iniPath) { + echo_style('green', ' '.$iniPath); +} else { + echo_style('warning', ' WARNING: No configuration file (php.ini) used by PHP!'); } -echo "* To be on the safe side, please also launch the requirements check\n"; -echo "* from your web server using the web/config.php script.\n"; -echo_title('Mandatory requirements'); +echo PHP_EOL.PHP_EOL; -$checkPassed = true; +echo '> Checking Symfony requirements:'.PHP_EOL.' '; + +$messages = array(); foreach ($symfonyRequirements->getRequirements() as $req) { /** @var $req Requirement */ - echo_requirement($req); - if (!$req->isFulfilled()) { - $checkPassed = false; + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('red', 'E'); + $messages['error'][] = $helpText; + } else { + echo_style('green', '.'); } } -echo_title('Optional recommendations'); +$checkPassed = empty($messages['error']); foreach ($symfonyRequirements->getRecommendations() as $req) { - echo_requirement($req); + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('yellow', 'W'); + $messages['warning'][] = $helpText; + } else { + echo_style('green', '.'); + } } +if ($checkPassed) { + echo_block('success', 'OK', 'Your system is ready to run Symfony2 projects', true); +} else { + echo_block('error', 'ERROR', 'Your system is not ready to run Symfony2 projects', true); + + echo_title('Fix the following mandatory requirements', 'red'); + + foreach ($messages['error'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +if (!empty($messages['warning'])) { + echo_title('Optional recommendations to improve your setup', 'yellow'); + + foreach ($messages['warning'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +echo PHP_EOL; +echo_style('title', 'Note'); +echo ' The command console could use a different php.ini file'.PHP_EOL; +echo_style('title', '~~~~'); +echo ' than the one used with your web server. To be on the'.PHP_EOL; +echo ' safe side, please check the requirements from your web'.PHP_EOL; +echo ' server using the '; +echo_style('yellow', 'web/config.php'); +echo ' script.'.PHP_EOL; +echo PHP_EOL; + exit($checkPassed ? 0 : 1); -/** - * Prints a Requirement instance - */ -function echo_requirement(Requirement $requirement) +function get_error_message(Requirement $requirement, $lineSize) { - $result = $requirement->isFulfilled() ? 'OK' : ($requirement->isOptional() ? 'WARNING' : 'ERROR'); - echo ' ' . str_pad($result, 9); - echo $requirement->getTestMessage() . "\n"; - - if (!$requirement->isFulfilled()) { - echo sprintf(" %s\n\n", $requirement->getHelpText()); + if ($requirement->isFulfilled()) { + return; } + + $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; + $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; + + return $errorMessage; } -function echo_title($title) +function echo_title($title, $style = null) { - echo "\n** $title **\n\n"; + $style = $style ?: 'title'; + + echo PHP_EOL; + echo_style($style, $title.PHP_EOL); + echo_style($style, str_repeat('~', strlen($title)).PHP_EOL); + echo PHP_EOL; +} + +function echo_style($style, $message) +{ + // ANSI color codes + $styles = array( + 'reset' => "\033[0m", + 'red' => "\033[31m", + 'green' => "\033[32m", + 'yellow' => "\033[33m", + 'error' => "\033[37;41m", + 'success' => "\033[37;42m", + 'title' => "\033[34m", + ); + $supports = has_color_support(); + + echo ($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); +} + +function echo_block($style, $title, $message) +{ + $message = ' '.trim($message).' '; + $width = strlen($message); + + echo PHP_EOL.PHP_EOL; + + echo_style($style, str_repeat(' ', $width).PHP_EOL); + echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL); + echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL); + echo_style($style, str_repeat(' ', $width).PHP_EOL); +} + +function has_color_support() +{ + static $support; + + if (null === $support) { + if (DIRECTORY_SEPARATOR == '\\') { + $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); + } else { + $support = function_exists('posix_isatty') && @posix_isatty(STDOUT); + } + } + + return $support; } diff --git a/app/config/config.yml b/app/config/config.yml index ad67c1d..a9fdf65 100755 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -60,7 +60,7 @@ doctrine: charset: UTF8 # if using pdo_sqlite as your database driver, add the path in parameters.yml # e.g. database_path: "%kernel.root_dir%/data/data.db3" - # path: "%database_path%" + path: "%database_path%" orm: auto_generate_proxy_classes: "%kernel.debug%" diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist old mode 100644 new mode 100755 index ebdabb5..64d8e1c --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -5,6 +5,7 @@ parameters: database_name: symfony database_user: root database_password: ~ + database_path: "%kernel.root_dir%/calcifer.sqlite3" mailer_transport: smtp mailer_host: 127.0.0.1 diff --git a/composer.json b/composer.json index 3ee53f9..4823ea7 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", - "jsvrcek/ics": "dev-master", + "enko/ics": "~0.1", "doctrine/migrations": "dev-master", "doctrine/doctrine-migrations-bundle": "dev-master", "jbroadway/urlify" : "~1.0" diff --git a/composer.lock b/composer.lock index db1aac7..d3cb91e 100755 --- 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": "a72c02cc5e14c865991a846b5bac02fb", + "hash": "77745a3287830b815f677d20df33b385", "packages": [ { "name": "doctrine/annotations", @@ -444,12 +444,12 @@ "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", - "reference": "f7138381aa884c0f679da4de41e369b94ead9cd3" + "reference": "81575a4316951125ce408c70f30547c77d98f78a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/f7138381aa884c0f679da4de41e369b94ead9cd3", - "reference": "f7138381aa884c0f679da4de41e369b94ead9cd3", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/81575a4316951125ce408c70f30547c77d98f78a", + "reference": "81575a4316951125ce408c70f30547c77d98f78a", "shasum": "" }, "require": { @@ -474,12 +474,6 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" @@ -487,6 +481,10 @@ { "name": "Doctrine Project", "homepage": "http://www.doctrine-project.org" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], "description": "Symfony DoctrineMigrationsBundle", @@ -496,7 +494,7 @@ "migrations", "schema" ], - "time": "2014-03-20 14:48:55" + "time": "2014-08-17 07:53:47" }, { "name": "doctrine/inflector", @@ -620,12 +618,12 @@ "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "4256449c5e2603a6b6ee5a78c7c4521d4d4430b8" + "reference": "1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/4256449c5e2603a6b6ee5a78c7c4521d4d4430b8", - "reference": "4256449c5e2603a6b6ee5a78c7c4521d4d4430b8", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021", + "reference": "1a9dffa64e33fdc10f4b4c3f5d7230b74d4a1021", "shasum": "" }, "require": { @@ -655,15 +653,13 @@ "LGPL" ], "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/", - "role": "Creator" - }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" } ], "description": "Database Schema migrations using Doctrine DBAL", @@ -672,20 +668,20 @@ "database", "migrations" ], - "time": "2014-07-09 07:58:02" + "time": "2014-08-18 18:03:07" }, { "name": "doctrine/orm", - "version": "v2.4.3", + "version": "v2.4.4", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "8a13376d42b5ea467727ffe730aa0e14ca3c5e29" + "reference": "fc19c3b53dcd00e6584db40669fdd699c4671f97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/8a13376d42b5ea467727ffe730aa0e14ca3c5e29", - "reference": "8a13376d42b5ea467727ffe730aa0e14ca3c5e29", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/fc19c3b53dcd00e6584db40669fdd699c4671f97", + "reference": "fc19c3b53dcd00e6584db40669fdd699c4671f97", "shasum": "" }, "require": { @@ -748,7 +744,59 @@ "database", "orm" ], - "time": "2014-06-10 11:49:08" + "time": "2014-07-11 03:05:53" + }, + { + "name": "enko/ics", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/enko/ICS.git", + "reference": "60416fc3842a7b4ee4f0938b8c35c96b402fee32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/enko/ICS/zipball/60416fc3842a7b4ee4f0938b8c35c96b402fee32", + "reference": "60416fc3842a7b4ee4f0938b8c35c96b402fee32", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "3.6.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Jsvrcek\\ICS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Svrcek", + "homepage": "https://github.com/jasvrcek" + }, + { + "name": "Tim Schumacher", + "homepage": "https://github.com/enko" + } + ], + "description": "abstraction layer for creating multi-byte safe RFC 5545 compliant .ics files", + "homepage": "https://github.com/enko/ICS", + "keywords": [ + ".ics", + "RFC 5545", + "calendar", + "export", + "ical", + "multi-byte safe" + ], + "time": "2014-07-30 23:43:46" }, { "name": "incenteev/composer-parameter-handler", @@ -918,54 +966,6 @@ }, "type": "library" }, - { - "name": "jsvrcek/ics", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/jasvrcek/ICS.git", - "reference": "85e3e34214547a9981bd3be38633f9dce4f85094" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jasvrcek/ICS/zipball/85e3e34214547a9981bd3be38633f9dce4f85094", - "reference": "85e3e34214547a9981bd3be38633f9dce4f85094", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "3.6.*" - }, - "type": "library", - "autoload": { - "psr-0": { - "Jsvrcek\\ICS\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Svrcek", - "homepage": "https://github.com/jasvrcek" - } - ], - "description": "abstraction layer for creating multi-byte safe RFC 5545 compliant .ics files", - "homepage": "https://github.com/jasvrcek/ICS", - "keywords": [ - ".ics", - "RFC 5545", - "calendar", - "export", - "ical", - "multi-byte safe" - ], - "time": "2013-10-28 17:21:17" - }, { "name": "knplabs/knp-markdown-bundle", "version": "1.3.2", @@ -1255,29 +1255,25 @@ }, { "name": "sensio/distribution-bundle", - "version": "v3.0.1", + "version": "v3.0.5", "target-dir": "Sensio/Bundle/DistributionBundle", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", - "reference": "e9caa300faf95076c8e27693f3fdb0bb6e3148c0" + "reference": "ad10123f2532f6e311e583cce203ef368eedc469" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/e9caa300faf95076c8e27693f3fdb0bb6e3148c0", - "reference": "e9caa300faf95076c8e27693f3fdb0bb6e3148c0", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/ad10123f2532f6e311e583cce203ef368eedc469", + "reference": "ad10123f2532f6e311e583cce203ef368eedc469", "shasum": "" }, "require": { "php": ">=5.3.3", + "sensiolabs/security-checker": "~2.0", "symfony/class-loader": "~2.2", - "symfony/config": "~2.2", - "symfony/dependency-injection": "~2.2", - "symfony/filesystem": "~2.2", "symfony/form": "~2.2", - "symfony/framework-bundle": "~2.2", - "symfony/http-foundation": "~2.2", - "symfony/http-kernel": "~2.2", + "symfony/framework-bundle": "~2.4", "symfony/process": "~2.2", "symfony/validator": "~2.2", "symfony/yaml": "~2.2" @@ -1300,17 +1296,15 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "email": "fabien@symfony.com" } ], - "description": "The base bundle for the Symfony Distributions", + "description": "Base bundle for Symfony Distributions", "keywords": [ "configuration", "distribution" ], - "time": "2014-06-06 02:53:20" + "time": "2014-08-26 13:14:47" }, { "name": "sensio/framework-extra-bundle", @@ -1369,6 +1363,51 @@ ], "time": "2014-05-22 23:27:44" }, + { + "name": "sensiolabs/security-checker", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/security-checker.git", + "reference": "5b4eb4743ebe68276c911c84101ecdf4a9ae76ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/5b4eb4743ebe68276c911c84101ecdf4a9ae76ee", + "reference": "5b4eb4743ebe68276c911c84101ecdf4a9ae76ee", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "symfony/console": "~2.0" + }, + "bin": [ + "security-checker" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-0": { + "SensioLabs\\Security": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "A security checker for your composer.lock", + "time": "2014-07-19 10:52:35" + }, { "name": "swiftmailer/swiftmailer", "version": "v5.2.1", @@ -1488,20 +1527,21 @@ }, { "name": "symfony/icu", - "version": "v1.2.1", + "version": "v1.2.2", "target-dir": "Symfony/Component/Icu", "source": { "type": "git", "url": "https://github.com/symfony/Icu.git", - "reference": "98e197da54df1f966dd5e8a4992135703569c987" + "reference": "d4d85d6055b87f394d941b45ddd3a9173e1e3d2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Icu/zipball/98e197da54df1f966dd5e8a4992135703569c987", - "reference": "98e197da54df1f966dd5e8a4992135703569c987", + "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" @@ -1532,21 +1572,20 @@ "icu", "intl" ], - "time": "2013-10-04 10:06:38" + "time": "2014-07-25 09:58:17" }, { "name": "symfony/monolog-bundle", - "version": "v2.6.0", - "target-dir": "Symfony/Bundle/MonologBundle", + "version": "v2.6.1", "source": { "type": "git", "url": "https://github.com/symfony/MonologBundle.git", - "reference": "e1d4aa99c7440b11e9dfbfef7ed63084401dbc6a" + "reference": "227bbeefe30f2d95e3fe5fbd1ccda414287a957a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/MonologBundle/zipball/e1d4aa99c7440b11e9dfbfef7ed63084401dbc6a", - "reference": "e1d4aa99c7440b11e9dfbfef7ed63084401dbc6a", + "url": "https://api.github.com/repos/symfony/MonologBundle/zipball/227bbeefe30f2d95e3fe5fbd1ccda414287a957a", + "reference": "227bbeefe30f2d95e3fe5fbd1ccda414287a957a", "shasum": "" }, "require": { @@ -1568,8 +1607,8 @@ } }, "autoload": { - "psr-0": { - "Symfony\\Bundle\\MonologBundle": "" + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1577,15 +1616,13 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], "description": "Symfony MonologBundle", @@ -1594,7 +1631,7 @@ "log", "logging" ], - "time": "2014-06-04 16:49:13" + "time": "2014-07-21 00:36:06" }, { "name": "symfony/swiftmailer-bundle", @@ -1655,16 +1692,16 @@ }, { "name": "symfony/symfony", - "version": "v2.5.1", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", - "reference": "e3d2844abc988bc467bb1593cd340700096b0ac0" + "reference": "f077a238c781f845487a7c81fea8033ccd0e6a02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/symfony/zipball/e3d2844abc988bc467bb1593cd340700096b0ac0", - "reference": "e3d2844abc988bc467bb1593cd340700096b0ac0", + "url": "https://api.github.com/repos/symfony/symfony/zipball/f077a238c781f845487a7c81fea8033ccd0e6a02", + "reference": "f077a238c781f845487a7c81fea8033ccd0e6a02", "shasum": "" }, "require": { @@ -1751,15 +1788,13 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, { "name": "Symfony Community", "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], "description": "The Symfony PHP framework", @@ -1767,7 +1802,7 @@ "keywords": [ "framework" ], - "time": "2014-07-08 14:42:08" + "time": "2014-08-06 07:03:01" }, { "name": "twig/extensions", @@ -1927,19 +1962,15 @@ "time": "2014-04-28 14:01:06" } ], - "aliases": [ - - ], + "aliases": [], "minimum-stability": "stable", "stability-flags": { - "jsvrcek/ics": 20, "doctrine/migrations": 20, "doctrine/doctrine-migrations-bundle": 20 }, + "prefer-stable": false, "platform": { "php": ">=5.3.3" }, - "platform-dev": [ - - ] + "platform-dev": [] } diff --git a/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php b/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php new file mode 100755 index 0000000..f697a78 --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Command/GenerateEventsCommand.php @@ -0,0 +1,88 @@ +setName('calcifer:events:generate') + ->setDescription('Generate events from repeating events') + ->addOption('duration', 'd', InputOption::VALUE_OPTIONAL, 'The duration you want to generate events into the future. Default is 2 monts','2 months') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $duration = \DateInterval::createFromDateString($input->getOption('duration')); + if ($duration instanceof \DateInterval) { + $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'); + $entities = $repo->findAll(); + foreach($entities as $entity) { + /** @var RepeatingEvent $entity */ + $period = new \DatePeriod($entity->nextdate,new \DateInterval($entity->repeating_pattern),$end); + $event = null; + foreach($period as $date) { + /** @var \DateTime $date */ + $output->writeln(sprintf("Creating Event %s for %s",$entity->summary,$date->format('Y-m-d H:i'))); + $event = new Event(); + $event->location = $entity->location; + $event->startdate = $date; + if ($entity->duration > 0) { + $duration = new \DateInterval("PT".$entity->duration.'H'); + /** @var \DateTime $enddate */ + $enddate = clone $date; + $enddate->add($duration); + $entity->enddate = $enddate; + } + $event->summary = $entity->summary; + $event->description = $entity->description; + $event->url = $entity->url; + $entityManager->persist($event); + $entityManager->flush(); + $event->slug = \URLify::filter($event->id . '-' . $event->summary,255,'de'); + $entityManager->persist($event); + $entityManager->flush(); + foreach($entity->getTags() as $tag) { + $event->addTag($tag); + } + $entityManager->persist($event); + $entityManager->flush(); + } + if (!is_null($event)) { + $entity->nextdate = $event->startdate; + $entity->nextdate->add(new \DateInterval($entity->repeating_pattern)); + $entityManager->persist($entity); + $entityManager->flush(); + } + } + } else { + $output->writeln('Invalid duration'); + } + + } +} diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php index 18dd67d..3397192 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/EventController.php @@ -59,76 +59,8 @@ class EventController extends Controller public function createAction(Request $request) { $entity = new Event(); - $entity->setDescription($request->get('description')); - $entity->setSummary($request->get('summary')); - $entity->setUrl($request->get('url')); - $startdate = $request->get('startdate'); - $startdate = new \DateTime($startdate); - $entity->setStartdate($startdate); - $entity->setSlug(\URLify::filter($entity->getSummary(),255,'de')); - $enddate = $request->get('enddate'); - if (strlen($enddate) > 0) { - $enddate = new \DateTime($enddate); - $entity->setenddate($enddate); - } - - $location = $request->get('location'); - $location_lat = $request->get('location_lat'); - $location_lon = $request->get('location_lon'); - if (strlen($location) > 0) { - // check if the location already exists - /** @var EntityManager $em */ - $em = $this->getDoctrine()->getManager(); - $repo = $em->getRepository('CalciferBundle:Location'); - $results = $repo->findBy(['name' => $location]); - if (count($results) > 0) { - $location_obj = $results[0]; - if (strlen($location_lat) > 0) { - $location_obj->setLat($location_lat); - } - if (strlen($location_lon) > 0) { - $location_obj->setLon($location_lon); - } - $em->persist($location_obj); - $em->flush(); - $entity->setLocation($results[0]); - } else { - $location_obj = new Location(); - $location_obj->setName($location); - if (strlen($location_lat) > 0) { - $location_obj->setLat($location_lat); - } - if (strlen($location_lon) > 0) { - $location_obj->setLon($location_lon); - } - $location_obj->setSlug(\URLify::filter($location_obj->getName(),255,'de')); - $em->persist($location_obj); - $em->flush(); - $entity->setLocation($location_obj); - } - } - - $tags = $request->get('tags'); - if (strlen($tags) > 0) { - $tags = explode(',',$tags); - $em = $this->getDoctrine()->getManager(); - $repo = $em->getRepository('CalciferBundle:Tag'); - foreach ($tags as $tag) { - $tag = trim($tag); - $results = $repo->findBy(['name' => $tag]); - if (count($results) > 0) { - $entity->addTag($results[0]); - } else { - $tag_obj = new Tag(); - $tag_obj->setName($tag); - $tag_obj->setSlug(\URLify::filter($tag_obj->getName(),255,'de')); - $em->persist($tag_obj); - $em->flush(); - $entity->addTag($tag_obj); - } - } - } + $em = $this->saveEvent($request, $entity); if ($entity->isValid()) { @@ -136,7 +68,7 @@ class EventController extends Controller $em->persist($entity); $em->flush(); - return $this->redirect($this->generateUrl('_show', array('slug' => $entity->getSlug()))); + return $this->redirect($this->generateUrl('_show', array('slug' => $entity->slug))); } return array( @@ -236,18 +168,44 @@ class EventController extends Controller throw $this->createNotFoundException('Unable to find Event entity.'); } - $entity->setDescription($request->get('description')); - $entity->setSummary($request->get('summary')); - $entity->setUrl($request->get('url')); + $em = $this->saveEvent($request, $entity); + + + if ($entity->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->persist($entity); + $em->flush(); + + return $this->redirect($this->generateUrl('_show', array('slug' => $entity->slug))); + } + + return array( + 'entity' => $entity, + + ); + } + + /** + * @param Request $request + * @param $entity + * @return EntityManager + */ + public function saveEvent(Request $request, Event $entity) + { + $entity->description = $request->get('description'); + $entity->summary = $request->get('summary'); + $entity->url = $request->get('url'); $startdate = $request->get('startdate'); $startdate = new \DateTime($startdate); - $entity->setStartdate($startdate); - $entity->setSlug(\URLify::filter($entity->getSummary(),255,'de')); + $entity->startdate = $startdate; + $entity->slug = \URLify::filter($entity->summary, 255, 'de'); $enddate = $request->get('enddate'); if (strlen($enddate) > 0) { $enddate = new \DateTime($enddate); - $entity->setenddate($enddate); + $entity->enddate = $enddate; + } else { + $entity->enddate = null; } $location = $request->get('location'); @@ -262,24 +220,24 @@ class EventController extends Controller if (count($results) > 0) { $location_obj = $results[0]; if (strlen($location_lat) > 0) { - $location_obj->setLat($location_lat); + $location_obj->lat = $location_lat; } if (strlen($location_lon) > 0) { - $location_obj->setLon($location_lon); + $location_obj->lon = $location_lon; } $em->persist($location_obj); $em->flush(); $entity->setLocation($results[0]); } else { $location_obj = new Location(); - $location_obj->setName($location); + $location_obj->name = $location; if (strlen($location_lat) > 0) { - $location_obj->setLat($location_lat); + $location_obj->lat = $location_lat; } if (strlen($location_lon) > 0) { - $location_obj->setLon($location_lon); + $location_obj->lon = $location_lon; } - $location_obj->setSlug(\URLify::filter($location_obj->getName(),255,'de')); + $location_obj->slug = \URLify::filter($location_obj->name, 255, 'de'); $em->persist($location_obj); $em->flush(); $entity->setLocation($location_obj); @@ -288,9 +246,10 @@ class EventController extends Controller $tags = $request->get('tags'); if (strlen($tags) > 0) { - $tags = explode(',',$tags); + $tags = explode(',', $tags); $em = $this->getDoctrine()->getManager(); $repo = $em->getRepository('CalciferBundle:Tag'); + $entity->clearTags(); foreach ($tags as $tag) { $tag = trim($tag); $results = $repo->findBy(['name' => $tag]); @@ -298,22 +257,47 @@ class EventController extends Controller $entity->addTag($results[0]); } else { $tag_obj = new Tag(); - $tag_obj->setName($tag); - $tag_obj->setSlug(\URLify::filter($tag_obj->getName(),255,'de')); + $tag_obj->name = $tag; + $tag_obj->slug = \URLify::filter($tag_obj->name, 255, 'de'); $em->persist($tag_obj); $em->flush(); $entity->addTag($tag_obj); } } + return $em; + } + return $em; + } + + /** + * Deletes a Event entity. + * + * @Route("/termine/{slug}/löschen", name="_delete") + * @Method({"GET", "POST"}) + * @Template("CalciferBundle:Event:delete.html.twig") + */ + public function deleteAction(Request $request, $slug) { + /** @var EntityManager $em */ + $em = $this->getDoctrine()->getManager(); + + /** @var EntityRepository $repo */ + $repo = $em->getRepository('CalciferBundle:Event'); + + /** @var Event $entity */ + $entity = $repo->findOneBy(['slug' => $slug]); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find Event entity.'); } - if ($entity->isValid()) { - $em = $this->getDoctrine()->getManager(); - $em->persist($entity); + $confirmation = $request->get('confirmation',false); + + if (($request->getMethod() == 'POST') && ($confirmation)) { + $em->remove($entity); $em->flush(); - return $this->redirect($this->generateUrl('_show', array('slug' => $entity->getSlug()))); + return $this->redirect('/'); } return array( @@ -321,4 +305,33 @@ class EventController extends Controller ); } + + /** + * Copies a Event entity. + * + * @Route("/termine/{slug}/kopieren", name="_copy") + * @Method("GET") + * @Template("CalciferBundle:Event:new.html.twig") + */ + public function copyAction(Request $request, $slug) { + /** @var EntityManager $em */ + $em = $this->getDoctrine()->getManager(); + + /** @var EntityRepository $repo */ + $repo = $em->getRepository('CalciferBundle:Event'); + + /** @var Event $entity */ + $entity = $repo->findOneBy(['slug' => $slug]); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find Event entity.'); + } + + $entity->id = null; + + return array( + 'entity' => $entity, + + ); + } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php index 3151254..631892a 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/LocationController.php @@ -2,6 +2,7 @@ namespace Hackspace\Bundle\CalciferBundle\Controller; +use Doctrine\Common\Annotations\Annotation\Required; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; @@ -23,7 +24,7 @@ use Jsvrcek\ICS\Model\Relationship\Organizer; use Jsvrcek\ICS\Utility\Formatter; use Jsvrcek\ICS\CalendarStream; use Jsvrcek\ICS\CalendarExport; -use Symfony\Component\Validator\Constraints\DateTime; +use Jsvrcek\ICS\Model\Description\Geo; /** * Location controller. @@ -35,11 +36,11 @@ class LocationController extends Controller /** * Finds and displays a Event entity. * - * @Route("/{slug}(?!\.ics)", name="location_show") + * @Route("/{slug}.{format}", name="location_show", defaults={"format" = "html"}) * @Method("GET") * @Template("CalciferBundle:Event:index.html.twig") */ - public function showAction($slug) + public function showAction($slug,$format) { /** @var EntityManager $em */ $em = $this->getDoctrine()->getManager(); @@ -67,52 +68,54 @@ class LocationController extends Controller ->andWhere('e.locations_id = :location') ->orderBy('e.startdate') ->setParameter('startdate',$now) - ->setParameter('location',$location->getId()); + ->setParameter('location',$location->id); $entities = $qb->getQuery()->execute(); - return array( - 'entities' => $entities, - 'location' => $location, - ); - } + if ($format == 'ics') { + $calendar = new Calendar(); + $calendar->setProdId('-//My Company//Cool Calendar App//EN'); - /** - * Finds and displays a Event entity. - * - * @Route("/{slug}.ics", name="location_show_ics") - * @Method("GET") - */ - public function showActionICS($slug) - { - $results = $this->showAction(str_replace('.ics','',$slug)); - $entities = $results['entities']; + 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]); + $calendar->addEvent($event); + } - $calendar = new Calendar(); - $calendar->setProdId('-//My Company//Cool Calendar App//EN'); + $calendarExport = new CalendarExport(new CalendarStream, new Formatter()); + $calendarExport->addCalendar($calendar); - foreach($entities as $entity) { - /** @var Event $entity */ - $event = new CalendarEvent(); - $event->setStart($entity->getStartdate()); - if ($entity->getEnddate() instanceof DateTime) - $event->setEnd($entity->getEnddate()); - $event->setSummary($entity->getSummary()); - $event->setDescription($entity->getDescription()); - $location = new \Jsvrcek\ICS\Model\Description\Location(); - $location->setName($entity->getLocation()->getName()); - $event->setLocations([$location]); - $calendar->addEvent($event); + //output .ics formatted text + $result = $calendarExport->getStream(); + + $response = new Response($result); + $response->headers->set('Content-Type', 'text/calendar'); + + return $response; + } else { + return array( + 'entities' => $entities, + 'location' => $location, + ); } - - $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; } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/RepeatingEventController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/RepeatingEventController.php new file mode 100755 index 0000000..db41dca --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/RepeatingEventController.php @@ -0,0 +1,262 @@ +getDoctrine()->getManager(); + + /** @var EntityRepository $repo */ + $repo = $em->getRepository('CalciferBundle:RepeatingEvent'); + + $entities = $repo->findAll(); + + return [ + 'entities' => $entities, + ]; + } + + /** + * Displays a form to create a repeating event + * + * @Route("/neu", name="repeating_event_new") + * @Method("GET") + * @Template() + */ + public function newAction() + { + $entity = new RepeatingEvent(); + + return [ + 'entity' => $entity, + ]; + } + + /** + * Creates a repeating event + * + * @Route("/neu", name="repeating_event_create") + * @Method("POST") + * @Template("CalciferBundle:RepeatingEvent:new.html.twig") + */ + public function createAction(Request $request) + { + $entity = new RepeatingEvent(); + $this->fillEntity($request, $entity); + if ($this->validateRepeatingEvent($entity)) { + $ret = $this->saveRepeatingEvent($request, $entity); + if ($entity->id > 0) { + return $this->redirect($this->generateUrl('repeating_event_show')); + } else { + throw new \Exception('Could not save repeating event?!?'); + } + } + return [ + 'entity' => $entity, + ]; + + } + + /** + * Displays a form to edit a repeating event + * + * @Route("/{slug}/bearbeiten",name="repeating_event_edit") + * @Method("GET") + * @Template() + */ + public function editAction($slug) + { + /** @var EntityManager $em */ + $em = $this->getDoctrine()->getManager(); + + /** @var EntityRepository $repo */ + $repo = $em->getRepository('CalciferBundle:RepeatingEvent'); + + /** @var Event $entity */ + $entity = $repo->findOneBy(['slug' => $slug]); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find RepeatingEvent entity.'); + } + + return array( + 'entity' => $entity, + ); + } + + /** + * Updates a repeating event + * + * @Route("/{slug}/bearbeiten",name="repeating_event_update") + * @Method("POST") + * @Template("CalciferBundle:RepeatingEvent:edit.html.twig") + */ + public function updateAction(Request $request, $slug) + { + /** @var EntityManager $em */ + $em = $this->getDoctrine()->getManager(); + + /** @var EntityRepository $repo */ + $repo = $em->getRepository('CalciferBundle:RepeatingEvent'); + + /** @var Event $entity */ + $entity = $repo->findOneBy(['slug' => $slug]); + + if (!$entity) { + throw $this->createNotFoundException('Unable to find RepeatingEvent entity.'); + } + + $this->fillEntity($request, $entity); + if ($this->validateRepeatingEvent($entity)) { + $ret = $this->saveRepeatingEvent($request, $entity); + if ($entity->id > 0) { + return $this->redirect($this->generateUrl('repeating_event_show')); + } else { + throw new \Exception('Could not save repeating event?!?'); + } + } + return [ + 'entity' => $entity, + ]; + } + + private function fillEntity(Request $request, RepeatingEvent $entity) + { + $fields = [ + 'duration', + 'repeating_pattern', + 'summary', + 'description', + 'url', + ]; + foreach ($fields as $field) { + $entity->$field = $request->get($field); + } + if (strlen($entity->duration) == 0) + $entity->duration = null; + $nextdate = $request->get('nextdate'); + $nextdate = new \DateTime($nextdate); + $entity->nextdate = $nextdate; + + } + + private function validateRepeatingEvent(RepeatingEvent $entity) + { + $fields = [ + 'nextdate', + 'repeating_pattern', + 'summary', + ]; + foreach ($fields as $field) { + if ((is_null($entity->$field)) && (strlen($entity->$field) > 0)) + return false; + } + return true; + } + + private function saveRepeatingEvent(Request $request, RepeatingEvent $entity) + { + $location = $request->get('location'); + $location_lat = $request->get('location_lat'); + $location_lon = $request->get('location_lon'); + if (strlen($location) > 0) { + // check if the location already exists + /** @var EntityManager $em */ + $em = $this->getDoctrine()->getManager(); + $repo = $em->getRepository('CalciferBundle:Location'); + $results = $repo->findBy(['name' => $location]); + if (count($results) > 0) { + $location_obj = $results[0]; + if (strlen($location_lat) > 0) { + $location_obj->lat = $location_lat; + } + if (strlen($location_lon) > 0) { + $location_obj->lon = $location_lon; + } + $em->persist($location_obj); + $em->flush(); + $entity->location = $results[0]; + } else { + $location_obj = new Location(); + $location_obj->name = $location; + if (strlen($location_lat) > 0) { + $location_obj->lat = $location_lat; + } + if (strlen($location_lon) > 0) { + $location_obj->lon = $location_lon; + } + $location_obj->slug = \URLify::filter($location_obj->name, 255, 'de'); + $em->persist($location_obj); + $em->flush(); + $entity->location = $location_obj; + } + } else { + $entity->location = null; + } + + $tags = $request->get('tags'); + if (strlen($tags) > 0) { + $tags = explode(',', $tags); + $em = $this->getDoctrine()->getManager(); + $repo = $em->getRepository('CalciferBundle:Tag'); + $entity->clearTags(); + foreach ($tags as $tag) { + $tag = trim($tag); + $results = $repo->findBy(['name' => $tag]); + if (count($results) > 0) { + $entity->addTag($results[0]); + } else { + $tag_obj = new Tag(); + $tag_obj->name = $tag; + $tag_obj->slug = \URLify::filter($tag_obj->name, 255, 'de'); + $em->persist($tag_obj); + $em->flush(); + $entity->addTag($tag_obj); + } + } + } else { + $entity->clearTags(); + } + + $entity->slug = \URLify::filter($entity->summary,255,'de'); + + $em = $this->getDoctrine()->getManager(); + $em->persist($entity); + $em->flush(); + + return $entity; + + } +} diff --git a/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php b/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php index b6128d9..dfb63f5 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php +++ b/src/Hackspace/Bundle/CalciferBundle/Controller/TagController.php @@ -7,6 +7,7 @@ use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; use Hackspace\Bundle\CalciferBundle\Entity\Location; use Hackspace\Bundle\CalciferBundle\Entity\Tag; +use Jsvrcek\ICS\Model\Description\Geo; use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; @@ -35,11 +36,11 @@ class TagController extends Controller /** * Finds and displays a Event entity. * - * @Route("/{slug}(?!\.ics)", name="tag_show") + * @Route("/{slug}.{format}", defaults={"format" = "html"}, name="tag_show") * @Method("GET") * @Template("CalciferBundle:Event:index.html.twig") */ - public function showAction($slug) + public function showAction($slug, $format) { /** @var EntityManager $em */ $em = $this->getDoctrine()->getManager(); @@ -55,60 +56,60 @@ class TagController extends Controller } $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') - ->join('e.tags', 't', 'WITH', $qb->expr()->in('t.id', $tag->getId())) + ->join('e.tags', 't', 'WITH', $qb->expr()->in('t.id', $tag->id)) ->where('e.startdate >= :startdate') ->orderBy('e.startdate') - ->setParameter('startdate',$now); + ->setParameter('startdate', $now); $entities = $qb->getQuery()->execute(); - return array( - 'entities' => $entities, - 'tag' => $tag, - ); - } + if ($format == 'ics') { + $calendar = new Calendar(); + $calendar->setProdId('-//My Company//Cool Calendar App//EN'); - /** - * Finds and displays a Event entity. - * - * @Route("/{slug}.ics", name="tag_show_ics") - * @Method("GET") - */ - public function showActionICS($slug) - { - $results = $this->showAction(str_replace('.ics','',$slug)); - $entities = $results['entities']; + 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); + 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); + } + } + $calendar->addEvent($event); + } - $calendar = new Calendar(); - $calendar->setProdId('-//My Company//Cool Calendar App//EN'); + $calendarExport = new CalendarExport(new CalendarStream, new Formatter()); + $calendarExport->addCalendar($calendar); - foreach($entities as $entity) { - /** @var Event $entity */ - $event = new CalendarEvent(); - $event->setStart($entity->getStartdate()); - $event->setEnd($entity->getEnddate()); - $event->setSummary($entity->getSummary()); - $event->setDescription($entity->getDescription()); - $location = new \Jsvrcek\ICS\Model\Description\Location(); - $location->setName($entity->getLocation()->getName()); - $event->setLocations([$location]); - $calendar->addEvent($event); + //output .ics formatted text + $result = $calendarExport->getStream(); + + $response = new Response($result); + $response->headers->set('Content-Type', 'text/calendar'); + + return $response; + } else { + return array( + 'entities' => $entities, + 'tag' => $tag, + ); } - - $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; } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/BaseEntity.php b/src/Hackspace/Bundle/CalciferBundle/Entity/BaseEntity.php new file mode 100755 index 0000000..ed3a198 --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/BaseEntity.php @@ -0,0 +1,63 @@ +$name; + } else { + throw new \Exception("Property {$name} does not Exists"); + } + } + + public function __set($name,$value) { + if (property_exists($this,$name)) { + $this->$name = $value; + return $this; + } else { + throw new \Exception("Property {$name} does not Exists"); + } + } +} \ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php index 82dfc4e..8a3a791 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Event.php @@ -3,59 +3,59 @@ namespace Hackspace\Bundle\CalciferBundle\Entity; use Doctrine\ORM\Mapping as ORM; -use Doctrine\ORM\PersistentCollection; /** * Event * + * @property \DateTime $startdate + * @property \DateTime $enddate + * @property string $summary + * @property string $description + * @property Location $location + * @property string $url + * @property array $tags + * * @ORM\Table(name="events") * @ORM\Entity */ -class Event +class Event extends BaseEntity { - /** - * @var integer - * - * @ORM\Column(name="id", type="integer") - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - */ - private $id; + use TagTrait; /** * @var \DateTime * * @ORM\Column(name="startdate", type="datetimetz") */ - private $startdate; + protected $startdate; /** * @var \DateTime * * @ORM\Column(name="enddate", type="datetimetz", nullable=true) */ - private $enddate; + protected $enddate; /** * @var string * * @ORM\Column(name="summary", type="string", length=255) */ - private $summary; + protected $summary; /** * @var string * * @ORM\Column(name="description", type="text", nullable=true) */ - private $description; + protected $description; /** * @var string * * @ORM\Column(name="locations_id", type="integer", nullable=true) */ - private $locations_id; + protected $locations_id; /** * @var Location @@ -63,14 +63,14 @@ class Event * @ORM\ManyToOne(targetEntity="Location") * @ORM\JoinColumn(name="locations_id", referencedColumnName="id") */ - private $location; + protected $location; /** * @var string * * @ORM\Column(name="url", type="string", length=255, nullable=true) */ - private $url; + protected $url; /** * @var array @@ -81,179 +81,7 @@ class Event * inverseJoinColumns={@ORM\JoinColumn(name="tags_id", referencedColumnName="id")} * ) */ - private $tags = []; - - /** - * @var string - * - * @ORM\Column(name="slug", type="string", length=255,options={"default" = ""}) - */ - private $slug = ''; - - /** - * @param string $slug - */ - public function setSlug($slug) - { - $this->slug = $slug; - } - - /** - * @return string - */ - public function getSlug() - { - return $this->slug; - } - - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Set startdate - * - * @param \DateTime $startdate - * @return Event - */ - public function setStartdate($startdate) - { - $this->startdate = $startdate; - - return $this; - } - - /** - * Get startdate - * - * @return \DateTime - */ - public function getStartdate() - { - return $this->startdate; - } - - /** - * Set enddate - * - * @param \DateTime $enddate - * @return Event - */ - public function setEnddate($enddate) - { - $this->enddate = $enddate; - - return $this; - } - - /** - * Get enddate - * - * @return \DateTime - */ - public function getEnddate() - { - return $this->enddate; - } - - /** - * Set summary - * - * @param string $summary - * @return Event - */ - public function setSummary($summary) - { - $this->summary = $summary; - - return $this; - } - - /** - * Get summary - * - * @return string - */ - public function getSummary() - { - return $this->summary; - } - - /** - * Set description - * - * @param string $description - * @return Event - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * Get description - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set location - * - * @param string $locations_id - * @return Event - */ - public function setLocationsID($locations_id) - { - $this->locations_id = $locations_id; - - return $this; - } - - /** - * Get location - * - * @return string - */ - public function getLocationsID() - { - return $this->locations_id; - } - - /** - * Set url - * - * @param string $url - * @return Event - */ - public function setUrl($url) - { - $this->url = $url; - - return $this; - } - - /** - * Get url - * - * @return string - */ - public function getUrl() - { - return $this->url; - } + protected $tags = []; /** * @param \Hackspace\Bundle\CalciferBundle\Entity\Location $location @@ -273,41 +101,20 @@ class Event return $this->location; } - public function getTags() { - return $this->tags; - } - - public function hasTag(Tag $tag) { - if ($this->tags instanceof PersistentCollection) { - return $this->tags->contains($tag); - } elseif (is_array($this->tags)) { - return in_array($tag,$this->tags); - } else { - return false; - } - - } - - public function addTag(Tag $tag) { - /** @var PersistentCollection $this->tags */ - if (!$this->hasTag($tag)) { - $this->tags[] = $tag; - } - } - public function isValid() { return true; } - public function getTagsAsText() { - if (count($this->tags) > 0) { - $tags = []; - foreach ($this->tags as $tag) { - $tags[] = $tag->getName(); + public function getFormatedDate() { + $retval = $this->startdate->format('Y-m-d H:i'); + if (!is_null($this->enddate)) { + $retval .= " — "; + if ($this->startdate->format('Y-m-d') == $this->enddate->format('Y-m-d')) { + $retval .= $this->enddate->format('H:i'); + } else { + $retval .= $this->enddate->format('Y-m-d H:i'); } - return implode(',',$tags); - } else { - return ''; } + return $retval; } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Location.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Location.php index 8d3b6a2..afd6feb 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Location.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Location.php @@ -7,141 +7,35 @@ use Doctrine\ORM\Mapping as ORM; /** * Location * + * @property string $name + * @property float $lon + * @property float $lat + * * @ORM\Table(name="locations") * @ORM\Entity */ -class Location +class Location extends BaseEntity { - /** - * @var integer - * - * @ORM\Column(name="id", type="integer") - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - */ - private $id; - /** * @var string * * @ORM\Column(name="name", type="string", length=255) */ - private $name; + protected $name; /** * @var float * * @ORM\Column(name="lon", type="float", nullable=true) */ - private $lon; + protected $lon; /** * @var float * * @ORM\Column(name="lat", type="float", nullable=true) */ - private $lat; - - /** - * @var string - * - * @ORM\Column(name="slug", type="string", length=255,options={"default" = ""}) - */ - private $slug = ''; - - /** - * @param string $slug - */ - public function setSlug($slug) - { - $this->slug = $slug; - } - - /** - * @return string - */ - public function getSlug() - { - return $this->slug; - } + protected $lat; - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Set name - * - * @param string $name - * @return Location - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set lon - * - * @param float $lon - * @return Location - */ - public function setLon($lon) - { - $this->lon = $lon; - - return $this; - } - - /** - * Get lon - * - * @return float - */ - public function getLon() - { - return $this->lon; - } - - /** - * Set lat - * - * @param float $lat - * @return Location - */ - public function setLat($lat) - { - $this->lat = $lat; - - return $this; - } - - /** - * Get lat - * - * @return float - */ - public function getLat() - { - return $this->lat; - } } diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/RepeatingEvent.php b/src/Hackspace/Bundle/CalciferBundle/Entity/RepeatingEvent.php new file mode 100755 index 0000000..d7a6bcd --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/RepeatingEvent.php @@ -0,0 +1,100 @@ +repeating_pattern) { + case 'P7D': + return 'Wöchentlich'; + case 'P14D': + return 'Alle 2 Wochen'; + case 'P1M': + return 'Monatlich'; + default: + return $this->repeating_pattern; + } + } +} \ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/Tag.php b/src/Hackspace/Bundle/CalciferBundle/Entity/Tag.php index ae4ad82..2e296ef 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Entity/Tag.php +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/Tag.php @@ -10,77 +10,12 @@ use Doctrine\ORM\Mapping as ORM; * @ORM\Table(name="tags") * @ORM\Entity */ -class Tag +class Tag extends BaseEntity { - /** - * @var integer - * - * @ORM\Column(name="id", type="integer") - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - */ - private $id; - /** * @var string * * @ORM\Column(name="name", type="string", length=255) */ - private $name; - - /** - * @var string - * - * @ORM\Column(name="slug", type="string", length=255,options={"default" = ""}) - */ - private $slug = ''; - - /** - * @param string $slug - */ - public function setSlug($slug) - { - $this->slug = $slug; - } - - /** - * @return string - */ - public function getSlug() - { - return $this->slug; - } - - /** - * Get id - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Set name - * - * @param string $name - * @return Tag - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } + protected $name; } diff --git a/src/Hackspace/Bundle/CalciferBundle/Entity/TagTrait.php b/src/Hackspace/Bundle/CalciferBundle/Entity/TagTrait.php new file mode 100755 index 0000000..952d990 --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Entity/TagTrait.php @@ -0,0 +1,61 @@ +tags; + } + + public function clearTags() + { + if ($this->tags instanceof PersistentCollection) { + $this->tags->clear(); + } elseif (is_array($this->tags)) { + $this->tags = []; + } + } + + public function hasTag(Tag $tag) + { + if ($this->tags instanceof PersistentCollection) { + return $this->tags->contains($tag); + } elseif (is_array($this->tags)) { + return in_array($tag, $this->tags); + } else { + return false; + } + + } + + public function addTag(Tag $tag) + { + if (!$this->hasTag($tag)) { + $this->tags[] = $tag; + } + } + + public function getTagsAsText() + { + if (count($this->tags) > 0) { + $tags = []; + foreach ($this->tags as $tag) { + $tags[] = $tag->name; + } + return implode(',', $tags); + } else { + return ''; + } + } +} \ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss index 867884c..6b615cb 100755 --- a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/events.scss @@ -6,13 +6,17 @@ } } - .startdate,.location,.url,.edit { + .startdate,.location,.url,.action { display: inline; margin: 0; margin-right: 0.5rem; margin-bottom: 0.5rem; } + a i.icon { + text-decoration: none; + } + ul.tags { padding-left: 0; margin: 0; diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss new file mode 100644 index 0000000..b4dd9dd --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/css/main.scss @@ -0,0 +1,37 @@ +body { + margin: 0; + font-family: 'Roboto', sans-serif; +} + +header { + top: 0; +} + +header .ui.grid > .column, .title.ui.grid > .column { + margin-top: 0; + margin-bottom: 0; +} + +.box h2 { + font-size: 1rem !important; +} + +a .icon { + text-decoration: none; +} + +a, a:hover, a:visited { + color: #000000; +} + +a:hover { + text-decoration: none; +} + +#mission-statement { + overflow: hidden; + + img { + margin-bottom: 0; + } +} \ No newline at end of file diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/images/logo.png b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/images/logo.png new file mode 100644 index 0000000..a377dab Binary files /dev/null and b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/images/logo.png differ diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/repeating_events.js b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/repeating_events.js new file mode 100755 index 0000000..3ffdf0e --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/assets/js/repeating_events.js @@ -0,0 +1,6 @@ +$(document).ready(function(){ + $('.ui.dropdown.selection') + .dropdown() + .dropdown('set value',$('.ui.dropdown.selection input[type=hidden]').val()) + ; +}); diff --git a/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/delete.html.twig b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/delete.html.twig new file mode 100755 index 0000000..66a4061 --- /dev/null +++ b/src/Hackspace/Bundle/CalciferBundle/Resources/views/Event/delete.html.twig @@ -0,0 +1,29 @@ +{% extends 'CalciferBundle::layout.html.twig' %} + +{% block css %} + {% stylesheets filter="compass" + "@CalciferBundle/Resources/assets/css/events.scss" %} + + {% endstylesheets %} +{% endblock %} + +{% block javascripts %} + {% javascripts + "@CalciferBundle/Resources/assets/js/events.js" %} + + {% endjavascripts %} +{% endblock %} + +{% block body -%} +
- Bearbeiten + {% if (detail|default(false)) %} +
++ Löschen +
+ ++ Kopieren +
+ {% endif %} +- {{ entity.startdate.format('Y-m-d H:i') }} + {{ entity.getFormatedDate() }}
{% if entity.location is not null %}- {{ entity.location.name }} + {{ entity.location.name }}
{% endif %} {% if entity.tags|length > 0 %} {% endif %} @@ -37,6 +53,5 @@ {% else %}{{ entity.description|markdown }}
{% endif %} -