diff --git a/.gitignore b/.gitignore index 51dccc8..46f52dd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ app/config/parameters.yml composer.phar behat.yml +.idea +!web/uploads/themes/.gitkeep +!web/uploads/themes/test.css +#composer.lock diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php deleted file mode 100644 index 28b0dcd..0000000 --- a/app/SymfonyRequirements.php +++ /dev/null @@ -1,764 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/* - * Users of PHP 5.2 should be able to run the requirements checks. - * This is why the file and all classes must be compatible with PHP 5.2+ - * (e.g. not using namespaces and closures). - * - * ************** CAUTION ************** - * - * DO NOT EDIT THIS FILE as it will be overridden by Composer as part of - * the installation/update process. The original file resides in the - * SensioDistributionBundle. - * - * ************** CAUTION ************** - */ - -/** - * Represents a single PHP requirement, e.g. an installed extension. - * It can be a mandatory requirement or an optional recommendation. - * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration. - * - * @author Tobias Schultze - */ -class Requirement -{ - private $fulfilled; - private $testMessage; - private $helpText; - private $helpHtml; - private $optional; - - /** - * Constructor that initializes the requirement. - * - * @param bool $fulfilled Whether the requirement is fulfilled - * @param string $testMessage The message for testing the requirement - * @param string $helpHtml The help text formatted in HTML for resolving the problem - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement - */ - public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false) - { - $this->fulfilled = (bool) $fulfilled; - $this->testMessage = (string) $testMessage; - $this->helpHtml = (string) $helpHtml; - $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText; - $this->optional = (bool) $optional; - } - - /** - * Returns whether the requirement is fulfilled. - * - * @return bool true if fulfilled, otherwise false - */ - public function isFulfilled() - { - return $this->fulfilled; - } - - /** - * Returns the message for testing the requirement. - * - * @return string The test message - */ - public function getTestMessage() - { - return $this->testMessage; - } - - /** - * Returns the help text for resolving the problem. - * - * @return string The help text - */ - public function getHelpText() - { - return $this->helpText; - } - - /** - * Returns the help text formatted in HTML. - * - * @return string The HTML help - */ - public function getHelpHtml() - { - return $this->helpHtml; - } - - /** - * Returns whether this is only an optional recommendation and not a mandatory requirement. - * - * @return bool true if optional, false if mandatory - */ - public function isOptional() - { - return $this->optional; - } -} - -/** - * Represents a PHP requirement in form of a php.ini configuration. - * - * @author Tobias Schultze - */ -class PhpIniRequirement extends Requirement -{ - /** - * Constructor that initializes the requirement. - * - * @param string $cfgName The configuration name used for ini_get() - * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, - * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement - * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. - * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. - * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. - * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) - * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement - */ - public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false) - { - $cfgValue = ini_get($cfgName); - - if (is_callable($evaluation)) { - if (null === $testMessage || null === $helpHtml) { - throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.'); - } - - $fulfilled = call_user_func($evaluation, $cfgValue); - } else { - if (null === $testMessage) { - $testMessage = sprintf('%s %s be %s in php.ini', - $cfgName, - $optional ? 'should' : 'must', - $evaluation ? 'enabled' : 'disabled' - ); - } - - if (null === $helpHtml) { - $helpHtml = sprintf('Set %s to %s in php.ini*.', - $cfgName, - $evaluation ? 'on' : 'off' - ); - } - - $fulfilled = $evaluation == $cfgValue; - } - - parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional); - } -} - -/** - * A RequirementCollection represents a set of Requirement instances. - * - * @author Tobias Schultze - */ -class RequirementCollection implements IteratorAggregate -{ - private $requirements = array(); - - /** - * Gets the current RequirementCollection as an Iterator. - * - * @return Traversable A Traversable interface - */ - public function getIterator() - { - return new ArrayIterator($this->requirements); - } - - /** - * Adds a Requirement. - * - * @param Requirement $requirement A Requirement instance - */ - public function add(Requirement $requirement) - { - $this->requirements[] = $requirement; - } - - /** - * Adds a mandatory requirement. - * - * @param bool $fulfilled Whether the requirement is fulfilled - * @param string $testMessage The message for testing the requirement - * @param string $helpHtml The help text formatted in HTML for resolving the problem - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null) - { - $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false)); - } - - /** - * Adds an optional recommendation. - * - * @param bool $fulfilled Whether the recommendation is fulfilled - * @param string $testMessage The message for testing the recommendation - * @param string $helpHtml The help text formatted in HTML for resolving the problem - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null) - { - $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true)); - } - - /** - * Adds a mandatory requirement in form of a php.ini configuration. - * - * @param string $cfgName The configuration name used for ini_get() - * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, - * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement - * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. - * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. - * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. - * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) - * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) - { - $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false)); - } - - /** - * Adds an optional recommendation in form of a php.ini configuration. - * - * @param string $cfgName The configuration name used for ini_get() - * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, - * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement - * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. - * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. - * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. - * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) - * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) - { - $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true)); - } - - /** - * Adds a requirement collection to the current set of requirements. - * - * @param RequirementCollection $collection A RequirementCollection instance - */ - public function addCollection(RequirementCollection $collection) - { - $this->requirements = array_merge($this->requirements, $collection->all()); - } - - /** - * Returns both requirements and recommendations. - * - * @return array Array of Requirement instances - */ - public function all() - { - return $this->requirements; - } - - /** - * Returns all mandatory requirements. - * - * @return array Array of Requirement instances - */ - public function getRequirements() - { - $array = array(); - foreach ($this->requirements as $req) { - if (!$req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns the mandatory requirements that were not met. - * - * @return array Array of Requirement instances - */ - public function getFailedRequirements() - { - $array = array(); - foreach ($this->requirements as $req) { - if (!$req->isFulfilled() && !$req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns all optional recommendations. - * - * @return array Array of Requirement instances - */ - public function getRecommendations() - { - $array = array(); - foreach ($this->requirements as $req) { - if ($req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns the recommendations that were not met. - * - * @return array Array of Requirement instances - */ - public function getFailedRecommendations() - { - $array = array(); - foreach ($this->requirements as $req) { - if (!$req->isFulfilled() && $req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns whether a php.ini configuration is not correct. - * - * @return bool php.ini configuration problem? - */ - public function hasPhpIniConfigIssue() - { - foreach ($this->requirements as $req) { - if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) { - return true; - } - } - - return false; - } - - /** - * Returns the PHP configuration file (php.ini) path. - * - * @return string|false php.ini file path - */ - public function getPhpIniConfigPath() - { - return get_cfg_var('cfg_file_path'); - } -} - -/** - * This class specifies all requirements and optional recommendations that - * are necessary to run the Symfony Standard Edition. - * - * @author Tobias Schultze - * @author Fabien Potencier - */ -class SymfonyRequirements extends RequirementCollection -{ - const REQUIRED_PHP_VERSION = '5.3.3'; - - /** - * Constructor that initializes the requirements. - */ - public function __construct() - { - /* mandatory requirements follow */ - - $installedPhpVersion = phpversion(); - - $this->addRequirement( - version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='), - sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion), - sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run. - Before using Symfony, upgrade your PHP installation, preferably to the latest version.', - $installedPhpVersion, self::REQUIRED_PHP_VERSION), - sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion) - ); - - $this->addRequirement( - version_compare($installedPhpVersion, '5.3.16', '!='), - 'PHP version must not be 5.3.16 as Symfony won\'t work properly with it', - 'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)' - ); - - $this->addRequirement( - is_dir(__DIR__.'/../vendor/composer'), - 'Vendor libraries must be installed', - 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. '. - 'Then run "php composer.phar install" to install them.' - ); - - $cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache'; - - $this->addRequirement( - is_writable($cacheDir), - 'app/cache/ or var/cache/ directory must be writable', - 'Change the permissions of either "app/cache/" or "var/cache/" directory so that the web server can write into it.' - ); - - $logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs'; - - $this->addRequirement( - is_writable($logsDir), - 'app/logs/ or var/logs/ directory must be writable', - 'Change the permissions of either "app/logs/" or "var/logs/" directory so that the web server can write into it.' - ); - - $this->addPhpIniRequirement( - 'date.timezone', true, false, - 'date.timezone setting must be set', - 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' - ); - - if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { - $timezones = array(); - foreach (DateTimeZone::listAbbreviations() as $abbreviations) { - foreach ($abbreviations as $abbreviation) { - $timezones[$abbreviation['timezone_id']] = true; - } - } - - $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()), - '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.' - ); - } - - $this->addRequirement( - function_exists('iconv'), - 'iconv() must be available', - 'Install and enable the iconv extension.' - ); - - $this->addRequirement( - function_exists('json_encode'), - 'json_encode() must be available', - 'Install and enable the JSON extension.' - ); - - $this->addRequirement( - function_exists('session_start'), - 'session_start() must be available', - 'Install and enable the session extension.' - ); - - $this->addRequirement( - function_exists('ctype_alpha'), - 'ctype_alpha() must be available', - 'Install and enable the ctype extension.' - ); - - $this->addRequirement( - function_exists('token_get_all'), - 'token_get_all() must be available', - 'Install and enable the Tokenizer extension.' - ); - - $this->addRequirement( - function_exists('simplexml_import_dom'), - 'simplexml_import_dom() must be available', - 'Install and enable the SimpleXML extension.' - ); - - if (function_exists('apc_store') && ini_get('apc.enabled')) { - if (version_compare($installedPhpVersion, '5.4.0', '>=')) { - $this->addRequirement( - version_compare(phpversion('apc'), '3.1.13', '>='), - 'APC version must be at least 3.1.13 when using PHP 5.4', - 'Upgrade your APC extension (3.1.13+).' - ); - } else { - $this->addRequirement( - version_compare(phpversion('apc'), '3.0.17', '>='), - 'APC version must be at least 3.0.17', - 'Upgrade your APC extension (3.0.17+).' - ); - } - } - - $this->addPhpIniRequirement('detect_unicode', false); - - if (extension_loaded('suhosin')) { - $this->addPhpIniRequirement( - 'suhosin.executor.include.whitelist', - create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), - false, - 'suhosin.executor.include.whitelist must be configured correctly in php.ini', - 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' - ); - } - - if (extension_loaded('xdebug')) { - $this->addPhpIniRequirement( - 'xdebug.show_exception_trace', false, true - ); - - $this->addPhpIniRequirement( - 'xdebug.scream', false, true - ); - - $this->addPhpIniRecommendation( - 'xdebug.max_nesting_level', - create_function('$cfgValue', 'return $cfgValue > 100;'), - true, - 'xdebug.max_nesting_level should be above 100 in php.ini', - 'Set "xdebug.max_nesting_level" to e.g. "250" in php.ini* to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.' - ); - } - - $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; - - $this->addRequirement( - null !== $pcreVersion, - 'PCRE extension must be available', - '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 */ - - if (file_exists(__DIR__.'/../vendor/composer')) { - require_once __DIR__.'/../vendor/autoload.php'; - - try { - $r = new ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle'); - - $contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php'); - } catch (ReflectionException $e) { - $contents = ''; - } - $this->addRecommendation( - file_get_contents(__FILE__) === $contents, - 'Requirements file should be up-to-date', - 'Your requirements file is outdated. Run composer install and re-check your configuration.' - ); - } - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.3.4', '>='), - 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions', - 'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.' - ); - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.3.8', '>='), - 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156', - 'Install PHP 5.3.8 or newer if your project uses annotations.' - ); - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.4.0', '!='), - 'You should not use PHP 5.4.0 due to the PHP bug #61453', - 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.' - ); - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.4.11', '>='), - 'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)', - 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.' - ); - - $this->addRecommendation( - (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<')) - || - version_compare($installedPhpVersion, '5.4.8', '>='), - 'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909', - 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.' - ); - - if (null !== $pcreVersion) { - $this->addRecommendation( - $pcreVersion >= 8.0, - sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), - 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.' - ); - } - - $this->addRecommendation( - class_exists('DomDocument'), - 'PHP-DOM and PHP-XML modules should be installed', - 'Install and enable the PHP-DOM and the PHP-XML modules.' - ); - - $this->addRecommendation( - function_exists('mb_strlen'), - 'mb_strlen() should be available', - 'Install and enable the mbstring extension.' - ); - - $this->addRecommendation( - function_exists('iconv'), - 'iconv() should be available', - 'Install and enable the iconv extension.' - ); - - $this->addRecommendation( - function_exists('utf8_decode'), - 'utf8_decode() should be available', - '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'), - 'posix_isatty() should be available', - 'Install and enable the php_posix extension (used to colorize the CLI output).' - ); - } - - $this->addRecommendation( - extension_loaded('intl'), - 'intl extension should be available', - 'Install and enable the intl extension (used for validators).' - ); - - if (extension_loaded('intl')) { - // in some WAMP server installations, new Collator() returns null - $this->addRecommendation( - null !== new Collator('fr_FR'), - 'intl extension should be correctly configured', - 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.' - ); - - // check for compatible ICU versions (only done when you have the intl extension) - if (defined('INTL_ICU_VERSION')) { - $version = INTL_ICU_VERSION; - } else { - $reflector = new ReflectionExtension('intl'); - - ob_start(); - $reflector->info(); - $output = strip_tags(ob_get_clean()); - - preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); - $version = $matches[1]; - } - - $this->addRecommendation( - version_compare($version, '4.0', '>='), - 'intl ICU version should be at least 4+', - 'Upgrade your intl extension with a newer ICU version (4+).' - ); - - $this->addPhpIniRecommendation( - 'intl.error_level', - create_function('$cfgValue', 'return (int) $cfgValue === 0;'), - true, - 'intl.error_level should be 0 in php.ini', - 'Set "intl.error_level" to "0" in php.ini* to inhibit the messages when an error occurs in ICU functions.' - ); - } - - $accelerator = - (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) - || - (extension_loaded('apc') && ini_get('apc.enabled')) - || - (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable')) - || - (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) - || - (extension_loaded('xcache') && ini_get('xcache.cacher')) - || - (extension_loaded('wincache') && ini_get('wincache.ocenabled')) - ; - - $this->addRecommendation( - $accelerator, - 'a PHP accelerator should be installed', - 'Install and/or enable a PHP accelerator (highly recommended).' - ); - - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $this->addRecommendation( - $this->getRealpathCacheSize() > 1000, - 'realpath_cache_size should be above 1024 in php.ini', - 'Set "realpath_cache_size" to e.g. "1024" in php.ini* to improve performance on windows.' - ); - } - - $this->addPhpIniRecommendation('short_open_tag', false); - - $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); - - $this->addPhpIniRecommendation('register_globals', false, true); - - $this->addPhpIniRecommendation('session.auto_start', false); - - $this->addRecommendation( - class_exists('PDO'), - 'PDO should be installed', - 'Install PDO (mandatory for Doctrine).' - ); - - if (class_exists('PDO')) { - $drivers = PDO::getAvailableDrivers(); - $this->addRecommendation( - count($drivers) > 0, - sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), - 'Install PDO drivers (mandatory for Doctrine).' - ); - } - } - - /** - * Loads realpath_cache_size from php.ini and converts it to int. - * - * (e.g. 16k is converted to 16384 int) - * - * @return int - */ - protected function getRealpathCacheSize() - { - $size = ini_get('realpath_cache_size'); - $size = trim($size); - $unit = strtolower(substr($size, -1, 1)); - switch ($unit) { - case 'g': - return $size * 1024 * 1024 * 1024; - case 'm': - return $size * 1024 * 1024; - case 'k': - return $size * 1024; - default: - return (int) $size; - } - } -} diff --git a/app/config/config.yml b/app/config/config.yml index 5eed146..888e5b3 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -24,6 +24,8 @@ framework: twig: debug: %kernel.debug% strict_variables: %kernel.debug% + globals: + theme: '%theme%' # Assetic Configuration assetic: diff --git a/app/config/parameters.circle.yml b/app/config/parameters.circle.yml index be32adb..b8f1abd 100644 --- a/app/config/parameters.circle.yml +++ b/app/config/parameters.circle.yml @@ -20,4 +20,8 @@ parameters: # default email for bot from which email is sent from_email: bot@email.com - admin_password: admin \ No newline at end of file + admin_password: admin + filestack.api_key: A3w1aZwZmQBibC09rAcZnz + theme: 'default' + themes.uploadPath: %kernel.root_dir%/../web/uploads/themes/ + themes.uploadUrl: /uploads/themes/ diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index b989851..56b79c2 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -21,3 +21,7 @@ parameters: from_email: bot@email.com admin_password: admin + filestack.api_key: A3w1aZwZmQBibC09rAcZnz + theme: 'default' + themes.uploadPath: %kernel.root_dir%/../web/uploads/themes/ + themes.uploadUrl: /uploads/themes/ diff --git a/circle.yml b/circle.yml index d0a97d3..5d2c30d 100644 --- a/circle.yml +++ b/circle.yml @@ -35,6 +35,7 @@ test: - chmod -R 777 app/logs - wget http://selenium-release.storage.googleapis.com/2.48/selenium-server-standalone-2.48.2.jar - nohup bash -c "java -jar selenium-server-standalone-2.48.2.jar &" + - chmod 777 -R web/uploads/themes/ override: - bin/phpspec run -fpretty --verbose --no-interaction - bin/behat --no-snippets --verbose -fpretty -p frontend diff --git a/features/backend/activeblocks.feature b/features/backend/activeblocks.feature new file mode 100644 index 0000000..8f4d85b --- /dev/null +++ b/features/backend/activeblocks.feature @@ -0,0 +1,136 @@ +@backend +Feature: Active blocks settings + In order to update active blocks + As an admin + I should be able to edit active blocks settings + +Background: + Given following "Event": + | ref | title | description | startDate | endDate | venue | email | host | + | event | My event | My another awesome event! | 2016-03-01 10:00 | 2016-03-01 18:00 | Burj Khalifa Tower | eventator@email.com | http://localhost:8000 | + | event2 | My other event | My other awesome event! | 2016-03-01 10:00 | 2016-03-01 18:00 | Burj Khalifa Tower | eventator@gmail.com | http://eventator.loc:8080 | + | event3 | His event | His another awesome event! | 2016-04-01 10:00 | 2016-04-01 18:00 | Kuala-lumpur Tower | eventator@gmail.com | http://event.com | + | event4 | Local event | My local awesome event! | 2017-14-11 12:26 | 2017-14-11 12:27 | Kuala-lumpur Tower | eventator@gmail.com | http://eventator.loc | + And following "EventTranslation": + | event | locale | + | event | ru_RU | + | event | de_DE | + | event2 | ru_RU | + | event2 | de_DE | + | event3 | ru_RU | + | event4 | ru_RU | + And following "Organizer": + | ref | title | description | isActive | events | + | organizer | My organizer | My another awesome organizer! | 1 | event,event2,event3 | + | organizer2 | His organizer | His another awesome organizer! | 1 | event2,event3,event4 | + And following "OrganizerTranslation": + | organizer | locale | + | organizer | ru_RU | + | organizer2 | de_DE | + And following "Speech": + | ref | title | description | language | event | + | speech | symfony propagation | world symfony expansion | ru | event | + | speech2 | php servers piece | php most popular language | en | event | + | speech3 | doctrine must have | what you docrtine project should have | en | event | + | speech4 | symfony propagation2 | world symfony expansion2 | en | event2 | + | speech5 | php servers piece2 | php most popular language2 | en | event2 | + | speech6 | doctrine must have2 | what you docrtine project should have2 | en | event2 | + | speech7 | symfony propagation2 | world symfony expansion2 | en | event3 | + | speech8 | php servers piece2 | php most popular language2 | en | event3 | + | speech9 | doctrine must have2 | what you docrtine project should have2 | en | event3 | + | speech0 | doctrine must have2 | what you docrtine project should have2 | en | event4 | + + And following "SpeechTranslation": + | speech | locale | + | speech | ru_RU | + | speech2 | de_DE | + | speech3 | de_DE | + | speech4 | ru_RU | + | speech5 | de_DE | + | speech6 | de_DE | + | speech7 | ru_RU | + | speech8 | de_DE | + | speech9 | de_DE | + | speech0 | de_DE | + And following "Program": + | ref | title | isTopic | isActive | startDate | endDate | events | speech | + | program | keynote | 1 | 1 | 2016-03-01 10:00 | 2016-03-01 10:30 | event | | + | program2 | alex_symfony | 0 | 1 | 2016-03-01 10:30 | 2016-03-01 11:30 | event | speech | + | program3 | phil_php | 0 | 1 | 2016-03-01 11:30 | 2016-03-01 12:30 | event | speech2 | + | program4 | coffee1 | 1 | 1 | 2016-03-01 12:30 | 2016-03-01 13:00 | event | | + | program5 | phil_doctrine | 0 | 1 | 2016-03-01 13:00 | 2016-03-01 14:30 | event | speech3 | + | program6 | end_keynote | 1 | 1 | 2016-03-01 14:30 | 2016-03-01 15:00 | event | | + | program7 | after_party | 1 | 1 | 2016-03-01 15:00 | 2016-03-01 18:00 | event | | + | program8 | keynote | 1 | 1 | 2016-04-01 10:00 | 2016-04-01 10:30 | event2 | | + | program9 | alex_symfony | 0 | 1 | 2016-04-01 10:30 | 2016-04-01 11:30 | event2 | speech4 | + | program10 | phil_php | 0 | 1 | 2016-04-01 11:30 | 2016-04-01 12:30 | event2 | speech5 | + | program11 | coffee1 | 1 | 1 | 2016-04-01 12:30 | 2016-04-01 13:00 | event2 | | + | program12 | phil_doctrine | 0 | 1 | 2016-04-01 13:00 | 2016-04-01 14:30 | event2 | speech6 | + | program13 | end_keynote | 1 | 1 | 2016-04-01 14:30 | 2016-04-01 15:00 | event2 | | + | program14 | after_party | 1 | 1 | 2016-04-01 15:00 | 2016-04-01 18:00 | event2 | | + | program15 | keynote | 1 | 1 | 2016-04-01 10:00 | 2016-04-01 10:30 | event3 | | + | program16 | alex_symfony | 0 | 1 | 2016-04-01 10:30 | 2016-04-01 11:30 | event3 | speech7 | + | program17 | phil_php | 0 | 1 | 2016-04-01 11:30 | 2016-04-01 12:30 | event3 | speech8 | + | program18 | coffee1 | 1 | 1 | 2016-04-01 12:30 | 2016-04-01 13:00 | event3 | | + | program19 | phil_doctrine | 0 | 1 | 2016-04-01 13:00 | 2016-04-01 14:30 | event3 | speech9 | + | program20 | end_keynote | 1 | 1 | 2016-04-01 14:30 | 2016-04-01 15:00 | event3 | | + | program21 | after_party | 1 | 1 | 2016-04-01 15:00 | 2016-04-01 18:00 | event3 | | + | program22 | after_party | 1 | 1 | 2016-04-01 15:00 | 2016-04-01 18:00 | event4 | | + And following "ProgramTranslation": + | program | locale | + | program | ru_RU | + | program2 | de_DE | + | program3 | de_DE | + | program4 | de_DE | + | program5 | de_DE | + | program6 | de_DE | + | program7 | de_DE | + | program8 | de_DE | + | program9 | de_DE | + | program10 | de_DE | + | program11 | de_DE | + | program12 | de_DE | + | program13 | de_DE | + | program14 | de_DE | + | program15 | de_DE | + | program16 | de_DE | + | program17 | de_DE | + | program18 | de_DE | + | program19 | de_DE | + | program20 | de_DE | + | program21 | de_DE | + | program22 | de_DE | + And following "Speaker": + | ref | firstName | lastName | Company | email | homepage | twitter | events | speeches | + | speaker | Phill | Pilow | Reseach Supplier | | | | event,event2,event3 | speech2,speech3,speech5,speech6,speech8,speech9 | + | speaker2 | Alex | Demchenko | KnpLabs | | http://451f.com.ua | https://twitter.com/twitter | event,event2,event3,event4 | speech,speech4,speech7,speech0 | + And following "SpeakerTranslation": + | speaker | locale | + | speaker | ru_RU | + | speaker2 | de_DE | + And following "Sponsor": + | ref | company | description | homepage | type | isActive | events | + | sponsor | Reseach Supplier | NASA research center | http://nasa.gov.us | 1 | 1 | event,event2,event3 | + | sponsor2 | KnpLabs | Happy awesome developer | http://knplabs.com | 2 | 1 | event,event4 | + And following "SponsorTranslation": + | sponsor | locale | + | sponsor | de_DE | + | sponsor2 | de_DE | + And following "Theme": + | title | is_active | + | test | 1 | + | test2 | 1 | +# And following "ShowBlocks": +# | showWhereItBeSection | showSpeakersSection | showScheduleSection | showAboutSection | showVenueSection | showMapSection | showHowItWasSection | showSponsorsSection | showOrganizersSection | showContactSection | +# | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + +@javascript +Scenario: Admin should have access to the active blocks manage + Given I am sign in as admin + When I click "Active Blocks" + Then I wait for a form + Then I should see "Active blocks settings" + And I uncheck "show_blocks_showAboutSection" + And I press "Save" + Then I wait for a form + Then I should see "Settings were updated" diff --git a/features/backend/themes.feature b/features/backend/themes.feature new file mode 100644 index 0000000..8ea5241 --- /dev/null +++ b/features/backend/themes.feature @@ -0,0 +1,189 @@ +@backend +Feature: Theme settings + In order to update themes settings + As an admin + I should be able to edit themes settings + +Background: + Given following "Event": + | ref | title | description | startDate | endDate | venue | email | host | + | event | My event | My another awesome event! | 2016-03-01 10:00 | 2016-03-01 18:00 | Burj Khalifa Tower | eventator@email.com | http://localhost:8000 | + | event2 | My other event | My other awesome event! | 2016-03-01 10:00 | 2016-03-01 18:00 | Burj Khalifa Tower | eventator@gmail.com | http://eventator.loc:8080 | + | event3 | His event | His another awesome event! | 2016-04-01 10:00 | 2016-04-01 18:00 | Kuala-lumpur Tower | eventator@gmail.com | http://event.com | + | event4 | Local event | My local awesome event! | 2017-14-11 12:26 | 2017-14-11 12:27 | Kuala-lumpur Tower | eventator@gmail.com | http://eventator.loc | + And following "EventTranslation": + | event | locale | + | event | ru_RU | + | event | de_DE | + | event2 | ru_RU | + | event2 | de_DE | + | event3 | ru_RU | + | event4 | ru_RU | + And following "Organizer": + | ref | title | description | isActive | events | + | organizer | My organizer | My another awesome organizer! | 1 | event,event2,event3 | + | organizer2 | His organizer | His another awesome organizer! | 1 | event2,event3,event4 | + And following "OrganizerTranslation": + | organizer | locale | + | organizer | ru_RU | + | organizer2 | de_DE | + And following "Speech": + | ref | title | description | language | event | + | speech | symfony propagation | world symfony expansion | ru | event | + | speech2 | php servers piece | php most popular language | en | event | + | speech3 | doctrine must have | what you docrtine project should have | en | event | + | speech4 | symfony propagation2 | world symfony expansion2 | en | event2 | + | speech5 | php servers piece2 | php most popular language2 | en | event2 | + | speech6 | doctrine must have2 | what you docrtine project should have2 | en | event2 | + | speech7 | symfony propagation2 | world symfony expansion2 | en | event3 | + | speech8 | php servers piece2 | php most popular language2 | en | event3 | + | speech9 | doctrine must have2 | what you docrtine project should have2 | en | event3 | + | speech0 | doctrine must have2 | what you docrtine project should have2 | en | event4 | + + And following "SpeechTranslation": + | speech | locale | + | speech | ru_RU | + | speech2 | de_DE | + | speech3 | de_DE | + | speech4 | ru_RU | + | speech5 | de_DE | + | speech6 | de_DE | + | speech7 | ru_RU | + | speech8 | de_DE | + | speech9 | de_DE | + | speech0 | de_DE | + And following "Program": + | ref | title | isTopic | isActive | startDate | endDate | events | speech | + | program | keynote | 1 | 1 | 2016-03-01 10:00 | 2016-03-01 10:30 | event | | + | program2 | alex_symfony | 0 | 1 | 2016-03-01 10:30 | 2016-03-01 11:30 | event | speech | + | program3 | phil_php | 0 | 1 | 2016-03-01 11:30 | 2016-03-01 12:30 | event | speech2 | + | program4 | coffee1 | 1 | 1 | 2016-03-01 12:30 | 2016-03-01 13:00 | event | | + | program5 | phil_doctrine | 0 | 1 | 2016-03-01 13:00 | 2016-03-01 14:30 | event | speech3 | + | program6 | end_keynote | 1 | 1 | 2016-03-01 14:30 | 2016-03-01 15:00 | event | | + | program7 | after_party | 1 | 1 | 2016-03-01 15:00 | 2016-03-01 18:00 | event | | + | program8 | keynote | 1 | 1 | 2016-04-01 10:00 | 2016-04-01 10:30 | event2 | | + | program9 | alex_symfony | 0 | 1 | 2016-04-01 10:30 | 2016-04-01 11:30 | event2 | speech4 | + | program10 | phil_php | 0 | 1 | 2016-04-01 11:30 | 2016-04-01 12:30 | event2 | speech5 | + | program11 | coffee1 | 1 | 1 | 2016-04-01 12:30 | 2016-04-01 13:00 | event2 | | + | program12 | phil_doctrine | 0 | 1 | 2016-04-01 13:00 | 2016-04-01 14:30 | event2 | speech6 | + | program13 | end_keynote | 1 | 1 | 2016-04-01 14:30 | 2016-04-01 15:00 | event2 | | + | program14 | after_party | 1 | 1 | 2016-04-01 15:00 | 2016-04-01 18:00 | event2 | | + | program15 | keynote | 1 | 1 | 2016-04-01 10:00 | 2016-04-01 10:30 | event3 | | + | program16 | alex_symfony | 0 | 1 | 2016-04-01 10:30 | 2016-04-01 11:30 | event3 | speech7 | + | program17 | phil_php | 0 | 1 | 2016-04-01 11:30 | 2016-04-01 12:30 | event3 | speech8 | + | program18 | coffee1 | 1 | 1 | 2016-04-01 12:30 | 2016-04-01 13:00 | event3 | | + | program19 | phil_doctrine | 0 | 1 | 2016-04-01 13:00 | 2016-04-01 14:30 | event3 | speech9 | + | program20 | end_keynote | 1 | 1 | 2016-04-01 14:30 | 2016-04-01 15:00 | event3 | | + | program21 | after_party | 1 | 1 | 2016-04-01 15:00 | 2016-04-01 18:00 | event3 | | + | program22 | after_party | 1 | 1 | 2016-04-01 15:00 | 2016-04-01 18:00 | event4 | | + And following "ProgramTranslation": + | program | locale | + | program | ru_RU | + | program2 | de_DE | + | program3 | de_DE | + | program4 | de_DE | + | program5 | de_DE | + | program6 | de_DE | + | program7 | de_DE | + | program8 | de_DE | + | program9 | de_DE | + | program10 | de_DE | + | program11 | de_DE | + | program12 | de_DE | + | program13 | de_DE | + | program14 | de_DE | + | program15 | de_DE | + | program16 | de_DE | + | program17 | de_DE | + | program18 | de_DE | + | program19 | de_DE | + | program20 | de_DE | + | program21 | de_DE | + | program22 | de_DE | + And following "Speaker": + | ref | firstName | lastName | Company | email | homepage | twitter | events | speeches | + | speaker | Phill | Pilow | Reseach Supplier | | | | event,event2,event3 | speech2,speech3,speech5,speech6,speech8,speech9 | + | speaker2 | Alex | Demchenko | KnpLabs | | http://451f.com.ua | https://twitter.com/twitter | event,event2,event3,event4 | speech,speech4,speech7,speech0 | + And following "SpeakerTranslation": + | speaker | locale | + | speaker | ru_RU | + | speaker2 | de_DE | + And following "Sponsor": + | ref | company | description | homepage | type | isActive | events | + | sponsor | Reseach Supplier | NASA research center | http://nasa.gov.us | 1 | 1 | event,event2,event3 | + | sponsor2 | KnpLabs | Happy awesome developer | http://knplabs.com | 2 | 1 | event,event4 | + And following "SponsorTranslation": + | sponsor | locale | + | sponsor | de_DE | + | sponsor2 | de_DE | + And following "Theme": + | title | is_active | + | test | 1 | + | test2 | 1 | + +@javascript +Scenario: Admin should have access to the theme manage + Given I am sign in as admin + When I click "Themes" + Then I wait for a form + Then I should see "Add Theme" + And I should see the row containing "1;test" + And I should see the row containing "2;test1" + When I click "Edit" on the row containing "1;test" + Then I wait for a form + Then I should see "test settings" + +@javascript +Scenario: Admin should be able to add theme + Given I am sign in as admin + When I click "Themes" + Then I wait for a form + Then I should see "Add Theme" + And I click "Add Theme" + Then I wait for a form + Then I should see "New theme settings" + And I fill in "Title" with "Test theme" + And I press "Upload file" + Then I wait "10" seconds + Then I should see " My Device " + And I attach the file "test.css" to "fsp-fileUpload" +# Then I wait "15" seconds +# Then I should see "Edit Image" + Then I wait "15" seconds + And I click on the element with css selector ".fsp-button--primary" + Then I wait "10" seconds + And I press "Add" + Then I wait for a form + Then I should see "Theme Test theme added." + Then I should see the row containing "3;Test theme" + +@javascript +Scenario: Admin should be able to update theme settings + Given I am sign in as admin + When I click "Themes" + Then I wait for a form + Then I should see "Add Theme" + And I should see the row containing "1;test" + When I click "Edit" on the row containing "1;test" + Then I wait for a form + Then I should see "test settings" + And I fill in "Title" with "testTest" + And I press "Update" + Then I wait for a form + Then I should see "Theme testTest updated." + Then I should see the row containing "1;testTest" + +@javascript +Scenario: Admin should be able to delete the theme + Given I am sign in as admin + When I click "Themes" + Then I wait for a form + Then I should see "Add Theme" + And I should see the row containing "1;testTest" + And I should see the row containing "2;test2" +# And I should see the row containing "3;Test theme" + Then I delete the record with id "2" + Then I wait for a form + Then I should see "Theme deleted." + Then I should not see the row containing "3;Test theme" + diff --git a/src/Event/EventBundle/Controller/Backend/ShowBlocksController.php b/src/Event/EventBundle/Controller/Backend/ShowBlocksController.php new file mode 100644 index 0000000..a16cd70 --- /dev/null +++ b/src/Event/EventBundle/Controller/Backend/ShowBlocksController.php @@ -0,0 +1,40 @@ +getRepository('EventEventBundle:ShowBlocks')->findOrCreate(); + $translator = $this->get('translator'); + $form = $this->createForm(ShowBlocksType::class, $showBlocks); + + if ($request->getMethod() === 'POST') { + $form->handleRequest($request); + + if ($form->isValid()) { + + $this->getManager()->persist($showBlocks); + $this->getManager()->flush(); + + $this->setNoticeFlash($translator->trans('Please clear cache to see changes')); + $this->setSuccessFlash($translator->trans('Settings were updated')); + + return $this->redirectToRoute('backend_show_blocks'); + } + } + + return $this->render('EventEventBundle:Backend/ShowBlocks:manage.html.twig', [ + 'showBlocks' => $showBlocks, + 'form' => $form->createView(), + ]); + } + +} diff --git a/src/Event/EventBundle/Controller/Backend/ThemeController.php b/src/Event/EventBundle/Controller/Backend/ThemeController.php new file mode 100644 index 0000000..4c39cb7 --- /dev/null +++ b/src/Event/EventBundle/Controller/Backend/ThemeController.php @@ -0,0 +1,110 @@ +render('EventEventBundle:Backend/Theme:index.html.twig', array( + 'themes' => $this->getRepository('EventEventBundle:Theme')->findAll() + )); + } + + public function manageAction(Request $request, $id = null) + { + $css_url = ''; + if ($id === null) { + $theme = new Theme(); + $theme->setChangedFile(true); + } else { + $theme = $this->findOr404('EventEventBundle:Theme', $id); + $css_url = $this->getUploadUrl() . $theme->getTitle() . '/css/style.css'; + } + + $form = $this->createForm(ThemeType::class, $theme); + + if ($request->getMethod() === 'POST') { + $form->handleRequest($request); + + if ($form->isValid()) { + if ($theme->getChangedFile()) { + $url = $request->request->get('file_url'); + $path = $this->getUploadPath(); + $file = $this->getFile($url); + $fs = new Filesystem(); + try { + $fs->dumpFile($path . $theme->getTitle() . '/css/style.css', $file, 0777); + } catch (IOExceptionInterface $e) { + throw new Exception($e->getMessage()); + } + } + + $this->getManager()->persist($theme); + $this->getManager()->flush(); + + $successFlashText = sprintf('Theme %s updated.', $theme->getTitle()); + if (!$id) { + $successFlashText = sprintf('Theme %s added.', $theme->getTitle()); + } + $this->setSuccessFlash($successFlashText); + + return $this->redirectToRoute('backend_theme'); + } + } + + return $this->render('EventEventBundle:Backend/Theme:manage.html.twig', [ + 'theme' => $theme, + 'form' => $form->createView(), + 'fs_api' => $this->container->getParameter('filestack.api_key'), + 'css_url' => $css_url, + ]); + } + + public function deleteAction($id) + { + $this->isGrantedAdmin(); + + $entity = $this->findOr404('EventEventBundle:Theme', $id); + $translator = $this->get('translator'); + try { + $fs = new Filesystem(); + $fs->remove($this->getUploadPath() . DIRECTORY_SEPARATOR . $entity->getTitle()); + } catch (IOExceptionInterface $e) { + throw new Exception($e->getMessage()); + } + + $this->getManager()->remove($entity); + $this->getManager()->flush(); + + + $this->setSuccessFlash($translator->trans('Theme deleted.')); + + return $this->redirectToRoute('backend_theme'); + } + + public function getUploadPath(){ + return $this->container->getParameter('themes.uploadPath'); + } + + public function getUploadUrl(){ + return $this->container->getParameter('themes.uploadUrl'); + } + + protected function getFile($url) + { + $client = new Client(); + $file = $client->createRequest('GET', $url)->send()->getBody(true); + return $file; + } + +} diff --git a/src/Event/EventBundle/Controller/Controller.php b/src/Event/EventBundle/Controller/Controller.php index 097192f..b9fdaf5 100644 --- a/src/Event/EventBundle/Controller/Controller.php +++ b/src/Event/EventBundle/Controller/Controller.php @@ -16,6 +16,11 @@ protected function getEvent() return $this->get('eventator.event_manager')->getCurrentEvent(); } + public function getBlocks() + { + return $this->getRepository('EventEventBundle:ShowBlocks')->findOrCreate(); + } + protected function getRepository($name) { return $this->getManager()->getRepository($name); diff --git a/src/Event/EventBundle/Controller/EventController.php b/src/Event/EventBundle/Controller/EventController.php index 08a467d..b3b5397 100755 --- a/src/Event/EventBundle/Controller/EventController.php +++ b/src/Event/EventBundle/Controller/EventController.php @@ -15,10 +15,18 @@ public function indexAction() return $this->render('EventEventBundle:Event:index.html.twig', []); } + public function whereItBeAction(){ + return $this->render('EventEventBundle:Component:_whereItBe.html.twig', [ + 'event' => $this->getEvent(), + 'blocks' => $this->getBlocks(), + ]); + } + public function carouselAction() { return $this->render('EventEventBundle:Component:_carousel.html.twig', [ - 'event' => $this->getEvent() + 'event' => $this->getEvent(), + 'blocks' => $this->getBlocks(), ]); } @@ -30,27 +38,32 @@ public function speakersAction() 'currentEvent' => $this->getEvent(), 'speakers' => $this->getEvent()->getSpeakers(), 'form' => $form->createView(), - 'captcha' => $this->getCaptcha('captchaResultCall') + 'captcha' => $this->getCaptcha('captchaResultCall'), + 'blocks' => $this->getBlocks(), ]); } public function aboutSymfonyAction() { return $this->render('EventEventBundle:Component:_about.html.twig', [ - 'event' => $this->getEvent() + 'event' => $this->getEvent(), + 'blocks' => $this->getBlocks(), ]); } public function venueAction() { return $this->render('EventEventBundle:Component:_venue.html.twig', [ - 'event' => $this->getEvent() + 'event' => $this->getEvent(), + 'blocks' => $this->getBlocks(), ]); } public function conferencesAction() { - return $this->render('EventEventBundle:Component:conferences.html.twig', []); + return $this->render('EventEventBundle:Component:conferences.html.twig', [ + 'blocks' => $this->getBlocks(), + ]); } public function scheduleAction(Request $request) @@ -58,21 +71,24 @@ public function scheduleAction(Request $request) $host = $request->getHttpHost(); return $this->render('EventEventBundle:Component:_schedule.html.twig', [ - 'schedule' => $this->getRepository('EventEventBundle:Event')->getProgram($host) + 'schedule' => $this->getRepository('EventEventBundle:Event')->getProgram($host), + 'blocks' => $this->getBlocks(), ]); } public function sponsorsAction() { return $this->render('EventEventBundle:Component:_sponsors.html.twig', [ - 'event' => $this->getEvent() + 'event' => $this->getEvent(), + 'blocks' => $this->getBlocks(), ]); } public function organizersAction() { return $this->render('EventEventBundle:Component:_organizers.html.twig', [ - 'event' => $this->getEvent() + 'event' => $this->getEvent(), + 'blocks' => $this->getBlocks(), ]); } @@ -102,7 +118,8 @@ public function contactAction(Request $request) return $this->render('EventEventBundle:Component:_contact.html.twig', [ 'event' => $event, 'form' => $form->createView(), - 'captcha' => $this->getCaptcha() + 'captcha' => $this->getCaptcha(), + 'blocks' => $this->getBlocks(), ]); } @@ -137,7 +154,8 @@ public function callForPaperAction(Request $request) return new Response($this->renderView('EventEventBundle:Event:_form.html.twig', [ 'form' => $form->createView(), - 'captcha' => $this->getCaptcha('captchaResultCall') + 'captcha' => $this->getCaptcha('captchaResultCall'), + 'blocks' => $this->getBlocks(), ])); } @@ -151,7 +169,8 @@ public function callForPaperViewAction() 'event' => $this->getEvent(), 'hosts' => $this->getHostYear(), 'form' => $form->createView(), - 'captcha' => $this->getCaptcha('captchaResultCall') + 'captcha' => $this->getCaptcha('captchaResultCall'), + 'blocks' => $this->getBlocks(), ])); } @@ -160,7 +179,8 @@ public function blockMenuAction() return new Response($this->renderView('@EventEvent/Component/_block_menu.html.twig', [ 'hosts' => $this->getHostYear(), 'event' => $this->getEvent(), - 'home_page' => true + 'home_page' => true, + 'blocks' => $this->getBlocks(), ])); } diff --git a/src/Event/EventBundle/Entity/Repository/ShowBlocksRepository.php b/src/Event/EventBundle/Entity/Repository/ShowBlocksRepository.php new file mode 100644 index 0000000..95b88ef --- /dev/null +++ b/src/Event/EventBundle/Entity/Repository/ShowBlocksRepository.php @@ -0,0 +1,21 @@ +findOneBy(array(), array('id' => 'ASC')); + if(!$entity){ + $entity = new ShowBlocks(); + $this->_em->persist($entity); + $this->_em->flush(); + } + return $entity; + } +} diff --git a/src/Event/EventBundle/Entity/Repository/ThemeRepository.php b/src/Event/EventBundle/Entity/Repository/ThemeRepository.php new file mode 100644 index 0000000..1bc6e69 --- /dev/null +++ b/src/Event/EventBundle/Entity/Repository/ThemeRepository.php @@ -0,0 +1,11 @@ +id; + } + + /** + * @return boolean + */ + public function getShowWhereItBeSection() + { + return $this->showWhereItBeSection; + } + + /** + * @param boolean $showWhereItBeSection + * @return ShowBlocks + */ + public function setShowWhereItBeSection($showWhereItBeSection) + { + $this->showWhereItBeSection = $showWhereItBeSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowSpeakersSection() + { + return $this->showSpeakersSection; + } + + /** + * @param boolean $showSpeakersSection + * @return ShowBlocks + */ + public function setShowSpeakersSection($showSpeakersSection) + { + $this->showSpeakersSection = $showSpeakersSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowScheduleSection() + { + return $this->showScheduleSection; + } + + /** + * @param boolean $showScheduleSection + * @return ShowBlocks + */ + public function setShowScheduleSection($showScheduleSection) + { + $this->showScheduleSection = $showScheduleSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowAboutSection() + { + return $this->showAboutSection; + } + + /** + * @param boolean $showAboutSection + * @return ShowBlocks + */ + public function setShowAboutSection($showAboutSection) + { + $this->showAboutSection = $showAboutSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowVenueSection() + { + return $this->showVenueSection; + } + + /** + * @param boolean $showVenueSection + * @return ShowBlocks + */ + public function setShowVenueSection($showVenueSection) + { + $this->showVenueSection = $showVenueSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowMapSection() + { + return $this->showMapSection; + } + + /** + * @param boolean $showMapSection + * @return ShowBlocks + */ + public function setShowMapSection($showMapSection) + { + $this->showMapSection = $showMapSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowHowItWasSection() + { + return $this->showHowItWasSection; + } + + /** + * @param boolean $showHowItWasSection + * @return ShowBlocks + */ + public function setShowHowItWasSection($showHowItWasSection) + { + $this->showHowItWasSection = $showHowItWasSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowSponsorsSection() + { + return $this->showSponsorsSection; + } + + /** + * @param boolean $showSponsorsSection + * @return ShowBlocks + */ + public function setShowSponsorsSection($showSponsorsSection) + { + $this->showSponsorsSection = $showSponsorsSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowOrganizersSection() + { + return $this->showOrganizersSection; + } + + /** + * @param boolean $showOrganizersSection + * @return ShowBlocks + */ + public function setShowOrganizersSection($showOrganizersSection) + { + $this->showOrganizersSection = $showOrganizersSection; + + return $this; + } + + /** + * @return boolean + */ + public function getShowContactSection() + { + return $this->showContactSection; + } + + /** + * @param boolean $showContactSection + * @return ShowBlocks + */ + public function setShowContactSection($showContactSection) + { + $this->showContactSection = $showContactSection; + + return $this; + } + +} diff --git a/src/Event/EventBundle/Entity/Theme.php b/src/Event/EventBundle/Entity/Theme.php new file mode 100644 index 0000000..9fa65fc --- /dev/null +++ b/src/Event/EventBundle/Entity/Theme.php @@ -0,0 +1,159 @@ +file = $this->title . DIRECTORY_SEPARATOR . 'css' . DIRECTORY_SEPARATOR . 'style.css'; + } + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set title + * + * @param string $title + * @return Theme + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get file + * + * @return string + */ + public function getFile() + { + return $this->file; + } + + /** + * Set file + * + * @param string $file + * @return Theme + */ + public function setFile($file) + { + $this->file = $file; + + return $this; + } + + /** + * Set isActive + * + * @param boolean $isActive + * @return Theme + */ + public function setIsActive($isActive) + { + $this->isActive = $isActive; + + return $this; + } + + /** + * Get isActive + * + * @return boolean + */ + public function getIsActive() + { + return $this->isActive; + } + + /** + * Set changedFile + * + * @param boolean $status + * @return Theme + */ + public function setChangedFile($status) + { + $this->changedFile = $status; + + return $this; + } + + /** + * Get isActive + * + * @return boolean + */ + public function getChangedFile() + { + return $this->changedFile; + } + + public function __toString() + { + return $this->title; + } +} diff --git a/src/Event/EventBundle/Form/Type/ShowBlocksType.php b/src/Event/EventBundle/Form/Type/ShowBlocksType.php new file mode 100644 index 0000000..1961e44 --- /dev/null +++ b/src/Event/EventBundle/Form/Type/ShowBlocksType.php @@ -0,0 +1,39 @@ +add('showWhereItBeSection', CheckboxType::class, ['required' => false]) + ->add('showSpeakersSection', CheckboxType::class, ['required' => false]) + ->add('showScheduleSection', CheckboxType::class, ['required' => false]) + ->add('showAboutSection', CheckboxType::class, ['required' => false]) + ->add('showVenueSection', CheckboxType::class, ['required' => false]) + ->add('showMapSection', CheckboxType::class, ['required' => false]) + ->add('showHowItWasSection', CheckboxType::class, ['required' => false]) + ->add('showSponsorsSection', CheckboxType::class, ['required' => false]) + ->add('showOrganizersSection', CheckboxType::class, ['required' => false]) + ->add('showContactSection', CheckboxType::class, ['required' => false]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => 'Event\EventBundle\Entity\ShowBlocks' + ]); + } + + public function getBlockPrefix() + { + return 'show_blocks'; + } +} diff --git a/src/Event/EventBundle/Form/Type/ThemeType.php b/src/Event/EventBundle/Form/Type/ThemeType.php new file mode 100644 index 0000000..ca6316d --- /dev/null +++ b/src/Event/EventBundle/Form/Type/ThemeType.php @@ -0,0 +1,40 @@ +add('title', TextType::class) + ->add('isActive', CheckboxType::class, ['required' => false]) + ->add('changedFile', CheckboxType::class, ['data' => false, 'required' => false]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => 'Event\EventBundle\Entity\Theme' + ]); + } + + public function getBlockPrefix() + { + return 'theme'; + } +} diff --git a/src/Event/EventBundle/Menu/Builder.php b/src/Event/EventBundle/Menu/Builder.php index d714cf4..e1a3b9b 100644 --- a/src/Event/EventBundle/Menu/Builder.php +++ b/src/Event/EventBundle/Menu/Builder.php @@ -34,6 +34,8 @@ public function sideBar(FactoryInterface $factory, array $options) $event->addChild('Sponsors', array('route' => 'backend_sponsor')); $event->addChild('Organizers', array('route' => 'backend_organizer')); $event->addChild('Calls For Paper', array('route' => 'backend_call_for_paper')); + $event->addChild('Themes', array('route' => 'backend_theme')); + $event->addChild('Active Blocks', array('route' => 'backend_show_blocks')); return $menu; } diff --git a/src/Event/EventBundle/Resources/config/routing/backend.yml b/src/Event/EventBundle/Resources/config/routing/backend.yml index ed61cb5..82a985f 100644 --- a/src/Event/EventBundle/Resources/config/routing/backend.yml +++ b/src/Event/EventBundle/Resources/config/routing/backend.yml @@ -169,3 +169,28 @@ backend_call_for_paper_delete: id: \d+ options: expose: true + +# Theme +backend_theme: + path: /themes + defaults: { _controller: EventEventBundle:Backend/Theme:index } + +backend_theme_add: + path: /theme/add + defaults: { _controller: EventEventBundle:Backend/Theme:manage } + +backend_theme_edit: + path: /theme/edit/{id} + defaults: { _controller: EventEventBundle:Backend/Theme:manage, id: null } + requirements: { id: \d+ } + +backend_theme_delete: + path: /theme/delete/{id} + defaults: { _controller: EventEventBundle:Backend/Theme:delete } + requirements: { id: \d+ } + +# Show blocks +backend_show_blocks: + path: /active_blocks + defaults: { _controller: EventEventBundle:Backend/ShowBlocks:manage } + diff --git a/src/Event/EventBundle/Resources/views/Backend/ShowBlocks/manage.html.twig b/src/Event/EventBundle/Resources/views/Backend/ShowBlocks/manage.html.twig new file mode 100644 index 0000000..df8ae1e --- /dev/null +++ b/src/Event/EventBundle/Resources/views/Backend/ShowBlocks/manage.html.twig @@ -0,0 +1,65 @@ +{% extends 'EventEventBundle:Backend:layout.html.twig' %} + +{% block content %} +
+ + + {{ form_start(form, {'method': 'POST', 'attr': {'id': 'showBlocks'}, 'action': path('backend_show_blocks', {'id': showBlocks.id})}) }} +
+ {{ form_label(form.showWhereItBeSection, 'Show "Where it be"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showWhereItBeSection) }} +
+
+ {{ form_label(form.showSpeakersSection, 'Show "Speakers"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showSpeakersSection) }} +
+
+ {{ form_label(form.showScheduleSection, 'Show "Schedule"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showScheduleSection) }} +
+
+ {{ form_label(form.showAboutSection, 'Show "About"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showAboutSection) }} +
+
+ {{ form_label(form.showVenueSection, 'Show "Venue"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showVenueSection) }} +
+
+ {{ form_label(form.showMapSection, 'Show "Map"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showMapSection) }} +
+
+ {{ form_label(form.showHowItWasSection, 'Show "How It Was"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showHowItWasSection) }} +
+
+ {{ form_label(form.showSponsorsSection, 'Show "Sponsors"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showSponsorsSection) }} +
+
+ {{ form_label(form.showOrganizersSection, 'Show "Organizers"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showOrganizersSection) }} +
+
+ {{ form_label(form.showContactSection, 'Show "Contact"', + { 'label_attr': {'class': 'control-label', 'style':'display:inline-block'} }) }} + {{ form_widget(form.showContactSection) }} +
+ + {{ form_end(form) }} + +
+{% endblock %} + diff --git a/src/Event/EventBundle/Resources/views/Backend/Theme/index.html.twig b/src/Event/EventBundle/Resources/views/Backend/Theme/index.html.twig new file mode 100644 index 0000000..c5af0c0 --- /dev/null +++ b/src/Event/EventBundle/Resources/views/Backend/Theme/index.html.twig @@ -0,0 +1,78 @@ +{% extends 'EventEventBundle:Backend:layout.html.twig' %} + +{% block content %} +
+ + + + + + + + + + + + {% for theme in themes %} + + + + + + {% else %} + + + + {% endfor %} + +
{{ 'ID' }}{{ 'Title'|trans }}{{ 'Actions'|trans }}
{{ theme.id }} + {{ theme.title }} + + +
{{ 'No themes found.'|trans }}
+
+{% endblock %} + +{% block javascripts %} + {{ parent() }} + + +{% endblock %} diff --git a/src/Event/EventBundle/Resources/views/Backend/Theme/manage.html.twig b/src/Event/EventBundle/Resources/views/Backend/Theme/manage.html.twig new file mode 100644 index 0000000..01550c9 --- /dev/null +++ b/src/Event/EventBundle/Resources/views/Backend/Theme/manage.html.twig @@ -0,0 +1,52 @@ +{% extends 'EventEventBundle:Backend:layout.html.twig' %} + +{% block content %} +
+ + + {{ form_start(form, {'method': 'POST', 'attr': {'id': 'theme'}, 'action': path('backend_theme_edit', {'id': theme.id})}) }} +
+
+ {{ form_row(form.title) }} + {% if theme.id %} + + {{ 'view style.css' }} + + {% endif %} +
+ + +
+
+ {{ form_row(form.isActive) }} + {{ form_row(form.changedFile) }} +
+
+ {{ form_rest(form) }} + + +
+ {{ form_end(form) }} + +
+{% endblock %} + +{% block javascripts %} + {{ parent() }} + + + +{% endblock %} diff --git a/src/Event/EventBundle/Resources/views/Component/_about.html.twig b/src/Event/EventBundle/Resources/views/Component/_about.html.twig index 221270d..825e873 100644 --- a/src/Event/EventBundle/Resources/views/Component/_about.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_about.html.twig @@ -1,4 +1,4 @@ -
+
@@ -60,4 +84,5 @@ $('#registration').modal('show'); }); }) - \ No newline at end of file + + diff --git a/src/Event/EventBundle/Resources/views/Component/_contact.html.twig b/src/Event/EventBundle/Resources/views/Component/_contact.html.twig index 57b9f6a..825d36a 100644 --- a/src/Event/EventBundle/Resources/views/Component/_contact.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_contact.html.twig @@ -1,6 +1,6 @@ {% form_theme form 'EventEventBundle::form_theme.html.twig' %}
-
+
@@ -64,6 +64,7 @@
+{% if blocks.showContactSection %} +{% endif %} diff --git a/src/Event/EventBundle/Resources/views/Component/_organizers.html.twig b/src/Event/EventBundle/Resources/views/Component/_organizers.html.twig index 9105b6c..99b1c3f 100644 --- a/src/Event/EventBundle/Resources/views/Component/_organizers.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_organizers.html.twig @@ -1,5 +1,5 @@ {% if event.organizers is not empty %} -
+

Organizers

diff --git a/src/Event/EventBundle/Resources/views/Component/_schedule.html.twig b/src/Event/EventBundle/Resources/views/Component/_schedule.html.twig index 0aff5e0..7852b0c 100644 --- a/src/Event/EventBundle/Resources/views/Component/_schedule.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_schedule.html.twig @@ -1,4 +1,4 @@ -
+

Schedule

@@ -45,4 +45,4 @@ {% endif %}
-
\ No newline at end of file +
diff --git a/src/Event/EventBundle/Resources/views/Component/_speakers.html.twig b/src/Event/EventBundle/Resources/views/Component/_speakers.html.twig index ac95b14..7a04208 100644 --- a/src/Event/EventBundle/Resources/views/Component/_speakers.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_speakers.html.twig @@ -1,4 +1,4 @@ -
+
@@ -23,4 +23,4 @@ {% include 'EventEventBundle:Event:_callForPaper.html.twig' with { 'form': form } %}
-
\ No newline at end of file +
diff --git a/src/Event/EventBundle/Resources/views/Component/_sponsors.html.twig b/src/Event/EventBundle/Resources/views/Component/_sponsors.html.twig index 7e9b15e..9062cb8 100644 --- a/src/Event/EventBundle/Resources/views/Component/_sponsors.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_sponsors.html.twig @@ -62,7 +62,7 @@ {% endif %} {% endmacro %} -
+

Sponsors

@@ -83,4 +83,4 @@ {{ _self.sponsors(event.specifiedSponsors) }} {% endif %}
-
\ No newline at end of file +
diff --git a/src/Event/EventBundle/Resources/views/Component/_venue.html.twig b/src/Event/EventBundle/Resources/views/Component/_venue.html.twig index 30e135e..366d919 100644 --- a/src/Event/EventBundle/Resources/views/Component/_venue.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/_venue.html.twig @@ -1,4 +1,4 @@ -
+
@@ -11,9 +11,10 @@
-
+
+{% if blocks.showMapSection %} +{% endif %} diff --git a/src/Event/EventBundle/Resources/views/Component/_whereItBe.html.twig b/src/Event/EventBundle/Resources/views/Component/_whereItBe.html.twig new file mode 100644 index 0000000..1df6175 --- /dev/null +++ b/src/Event/EventBundle/Resources/views/Component/_whereItBe.html.twig @@ -0,0 +1,14 @@ +
+
+

Where will it be?

+

+ {{ event.venue }}, {{ event.country ~ ' ' ~ event.city }} / + {{ event.startDate|date }} +

+
+
+
+

{{ event.description|raw }}

+
+
+
diff --git a/src/Event/EventBundle/Resources/views/Component/conferences.html.twig b/src/Event/EventBundle/Resources/views/Component/conferences.html.twig index b29b375..18b0b1a 100644 --- a/src/Event/EventBundle/Resources/views/Component/conferences.html.twig +++ b/src/Event/EventBundle/Resources/views/Component/conferences.html.twig @@ -1,4 +1,4 @@ -
-
\ No newline at end of file +
diff --git a/src/Event/EventBundle/Resources/views/Event/callForPaperView.html.twig b/src/Event/EventBundle/Resources/views/Event/callForPaperView.html.twig index 9dc86ee..da5c7bb 100755 --- a/src/Event/EventBundle/Resources/views/Event/callForPaperView.html.twig +++ b/src/Event/EventBundle/Resources/views/Event/callForPaperView.html.twig @@ -4,7 +4,7 @@ {% block title %}Call for paper{% endblock %} {% block body %} - {% include 'EventEventBundle:Component:_block_menu.html.twig' with {'home_page': false} %} + {% include 'EventEventBundle:Component:_block_menu.html.twig' with {'home_page': false, 'blocks': blocks} %}
diff --git a/src/Event/EventBundle/Resources/views/base.html.twig b/src/Event/EventBundle/Resources/views/base.html.twig index d7edc8e..cd704e4 100644 --- a/src/Event/EventBundle/Resources/views/base.html.twig +++ b/src/Event/EventBundle/Resources/views/base.html.twig @@ -9,7 +9,15 @@ - + {% if theme is defined %} + {% if theme == 'default' %} + {% set css_path = 'bundles/eventevent/css/allstyle.css' %} + {% else %} + {% set css_path = 'uploads/themes/' ~ theme ~ '/css/style.css' %} + {% endif %} + {% endif %} + + {% block stylesheets %}{% endblock %} @@ -19,6 +27,7 @@ + {% block body %} {% endblock %} diff --git a/src/Event/EventBundle/Resources/views/layout.html.twig b/src/Event/EventBundle/Resources/views/layout.html.twig index 332c049..5317b80 100644 --- a/src/Event/EventBundle/Resources/views/layout.html.twig +++ b/src/Event/EventBundle/Resources/views/layout.html.twig @@ -8,49 +8,36 @@ {{ render(controller('EventEventBundle:Event:blockMenu')) }} {% endblock %} - {{ render(controller('EventEventBundle:Event:carousel')) }} + {{ render(controller('EventEventBundle:Event:carousel')) }} -
-
-

Where will it be?

-

- {{ event.venue }}, {{ event.country ~ ' ' ~ event.city }} / - {{ event.startDate|date }} -

-
-
-
-

{{ event.description|raw }}

-
-
-
+ {{ render(controller('EventEventBundle:Event:whereItBe')) }} - {{ render(controller('EventEventBundle:Event:speakers')) }} + {{ render(controller('EventEventBundle:Event:speakers')) }} - {{ render(controller('EventEventBundle:Event:schedule')) }} + {{ render(controller('EventEventBundle:Event:schedule')) }} - {{ render(controller('EventEventBundle:Event:aboutSymfony')) }} + {{ render(controller('EventEventBundle:Event:aboutSymfony')) }} - {{ render(controller('EventEventBundle:Event:venue')) }} + {{ render(controller('EventEventBundle:Event:venue')) }} - {{ render(controller('EventEventBundle:Event:conferences')) }} + {{ render(controller('EventEventBundle:Event:conferences')) }} - {{ render(controller('EventEventBundle:Event:sponsors')) }} + {{ render(controller('EventEventBundle:Event:sponsors')) }} - {{ render(controller('EventEventBundle:Event:organizers')) }} + {{ render(controller('EventEventBundle:Event:organizers')) }} - {{ render(controller('EventEventBundle:Event:contact')) }} + {{ render(controller('EventEventBundle:Event:contact')) }} - + $('#callForPaper').modal('show'); + }); + }) + {% include 'EventEventBundle:Event:_footer.html.twig' %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/var/ci/behat.ci.yml b/var/ci/behat.ci.yml index bff84ae..f9a0b3a 100644 --- a/var/ci/behat.ci.yml +++ b/var/ci/behat.ci.yml @@ -13,6 +13,7 @@ backend: browser_name: chrome goutte: ~ selenium2: ~ + files_path: %behat.paths.base%/web/uploads/themes/ Behat\Symfony2Extension\Extension: mink_driver: true diff --git a/web/uploads/themes/test.css b/web/uploads/themes/test.css new file mode 100644 index 0000000..5d17f1a --- /dev/null +++ b/web/uploads/themes/test.css @@ -0,0 +1 @@ +/* test css */