diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a1c8d8c6f..cd28fab482 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ We would ❤️ for you to contribute to Appwrite and help make it better! We wa ## How to Start? -If you are worried or don’t know where to start, check out our next section explaining what kind of help we could use and where can you get involved. You can reach out with questions to [Eldad Fux (@eldadfux)](https://twitter.com/eldadfux) or [@appwrite_io](https://twitter.com/appwrite_io) on Twitter, and anyone from the [Appwrite team on Discord](https://discord.gg/GSeTUeA). You can also submit an issue, and a maintainer can guide you! +If you are worried or don’t know where to start, check out our next section explaining what kind of help we could use and where can you get involved. You can reach out with questions to [Eldad Fux (@eldadfux)](https://twitter.com/eldadfux) or [@appwrite](https://twitter.com/appwrite) on Twitter, and anyone from the [Appwrite team on Discord](https://discord.gg/GSeTUeA). You can also submit an issue, and a maintainer can guide you! ## Code of Conduct @@ -406,7 +406,7 @@ Pull requests are great, but there are many other areas where you can help Appwr ### Blogging & Speaking -Blogging, speaking about, or creating tutorials about one of Appwrite’s many features. Mention [@appwrite_io](https://twitter.com/appwrite_io) on Twitter and/or [email team@appwrite.io](mailto:team@appwrite.io) so we can give pointers and tips and help you spread the word by promoting your content on the different Appwrite communication channels. Please add your blog posts and videos of talks to our [Awesome Appwrite](https://github.com/appwrite/awesome-appwrite) repo on GitHub. +Blogging, speaking about, or creating tutorials about one of Appwrite’s many features. Mention [@appwrite](https://twitter.com/appwrite) on Twitter and/or [email team@appwrite.io](mailto:team@appwrite.io) so we can give pointers and tips and help you spread the word by promoting your content on the different Appwrite communication channels. Please add your blog posts and videos of talks to our [Awesome Appwrite](https://github.com/appwrite/awesome-appwrite) repo on GitHub. ### Presenting at Meetups diff --git a/README.md b/README.md index e71cbf57e9..d61a286fb8 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@

[![Hacktoberfest](https://img.shields.io/static/v1?label=hacktoberfest&message=friendly&color=90a88b&style=flat-square)](https://hacktoberfest.appwrite.io) -[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) +[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord?r=Github) [![Docker Pulls](https://img.shields.io/docker/pulls/appwrite/appwrite?color=f02e65&style=flat-square)](https://hub.docker.com/r/appwrite/appwrite) [![Build Status](https://img.shields.io/travis/com/appwrite/appwrite?style=flat-square)](https://travis-ci.com/appwrite/appwrite) -[![Twitter Account](https://img.shields.io/twitter/follow/appwrite_io?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite_io) +[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) [![Translate](https://img.shields.io/badge/translate-f02e65?style=flat-square)](docs/tutorials/add-translations.md) @@ -155,7 +155,7 @@ For security issues, kindly email us at [security@appwrite.io](mailto:security@a ## Follow Us -Join our growing community around the world! See our official [Blog](https://medium.com/appwrite-io). Follow us on [Twitter](https://twitter.com/appwrite_io), [Facebook Page](https://www.facebook.com/appwrite.io), [Facebook Group](https://www.facebook.com/groups/appwrite.developers/) , [Dev Community](https://dev.to/appwrite) or join our live [Discord server](https://discord.gg/GSeTUeA) for more help, ideas, and discussions. +Join our growing community around the world! See our official [Blog](https://medium.com/appwrite-io). Follow us on [Twitter](https://twitter.com/appwrite), [Facebook Page](https://www.facebook.com/appwrite.io), [Facebook Group](https://www.facebook.com/groups/appwrite.developers/) , [Dev Community](https://dev.to/appwrite) or join our live [Discord server](https://discord.gg/GSeTUeA) for more help, ideas, and discussions. ## License diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 3759c63ad2..51b60277f0 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -1045,7 +1045,7 @@ App::post('/v1/database/collections/:collectionId/attributes/float') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal,$database, $audits, $usage) { + ->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ /** @var Utopia\Database\Database $dbForExternal*/ @@ -1060,6 +1060,11 @@ App::post('/v1/database/collections/:collectionId/attributes/float') if ($min > $max) { throw new Exception('Minimum value must be lesser than maximum value', 400); } + + // Ensure default value is a float + if (!is_null($default)) { + $default = \floatval($default); + } $validator = new Range($min, $max, Database::VAR_FLOAT); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 1cfab29b9e..d68accf560 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -628,6 +628,7 @@ App::post('/v1/storage/buckets/:bucketId/files') if($bucket->getAttribute('encryption', true) && $size <= APP_LIMIT_ENCRYPTION) { $key = App::getEnv('_APP_OPENSSL_KEY_V1'); $iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM)); + $tag = null; $data = OpenSSL::encrypt($data, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag); } @@ -651,6 +652,10 @@ App::post('/v1/storage/buckets/:bucketId/files') 'sizeActual' => $sizeActual, 'algorithm' => empty($compressor) ? '' : $compressor->getName(), 'comment' => '', + 'openSSLVersion' => '1', + 'openSSLCipher' => OpenSSL::CIPHER_AES_128_GCM, + 'openSSLTag' => \bin2hex($tag ?? ''), + 'openSSLIV' => \bin2hex($iv), 'search' => implode(' ', [$fileId, $file['name'] ?? '',]), ]; diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index a5d412d5b6..aaf2ee730c 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -695,7 +695,7 @@ App::delete('/v1/users/:userId/sessions') $dbForInternal->deleteDocument('sessions', $session->getId()); } - $dbForInternal->updateDocument('users', $user->getId(), $user->getAttribute('sessions', [])); + $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); $events ->setParam('eventData', $response->output($user, Response::MODEL_USER)) diff --git a/app/controllers/general.php b/app/controllers/general.php index e75b2f2164..2b52a03dbb 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -5,7 +5,7 @@ require_once __DIR__.'/../init.php'; use Utopia\App; use Utopia\Swoole\Request; use Appwrite\Utopia\Response; -use Utopia\View; +use Appwrite\Utopia\View; use Utopia\Exception; use Utopia\Config\Config; use Utopia\Domains\Domain; @@ -298,7 +298,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) { /** @var Utopia\App $utopia */ /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ /** @var Utopia\Database\Document $project */ if ($error instanceof PDOException) { diff --git a/app/controllers/shared/web.php b/app/controllers/shared/web.php index 3ebc410805..37bfb0130e 100644 --- a/app/controllers/shared/web.php +++ b/app/controllers/shared/web.php @@ -7,7 +7,7 @@ App::init(function ($utopia, $request, $response, $layout) { /** @var Utopia\App $utopia */ /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ /* AJAX check */ if (!empty($request->getQuery('version', ''))) { diff --git a/app/controllers/web/console.php b/app/controllers/web/console.php index 6c2d2ae912..f15b1b8cb4 100644 --- a/app/controllers/web/console.php +++ b/app/controllers/web/console.php @@ -1,14 +1,14 @@ setParam('description', 'Appwrite Console allows you to easily manage, monitor, and control your entire backend API and tools.') @@ -18,7 +18,7 @@ App::init(function ($layout) { App::shutdown(function ($response, $layout) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $header = new View(__DIR__.'/../../views/console/comps/header.phtml'); $footer = new View(__DIR__.'/../../views/console/comps/footer.phtml'); @@ -43,7 +43,7 @@ App::get('/error/:code') ->param('code', null, new \Utopia\Validator\Numeric(), 'Valid status code number', false) ->inject('layout') ->action(function ($code, $layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/error.phtml'); @@ -62,7 +62,7 @@ App::get('/console') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/index.phtml'); @@ -81,7 +81,7 @@ App::get('/console/account') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/account/index.phtml'); @@ -102,7 +102,7 @@ App::get('/console/notifications') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/v1/console/notifications/index.phtml'); @@ -117,7 +117,7 @@ App::get('/console/home') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/home/index.phtml'); $page @@ -133,7 +133,7 @@ App::get('/console/settings') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); @@ -157,7 +157,7 @@ App::get('/console/webhooks') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/webhooks/index.phtml'); @@ -176,7 +176,7 @@ App::get('/console/keys') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $scopes = array_keys(Config::getParam('scopes')); $page = new View(__DIR__.'/../../views/console/keys/index.phtml'); @@ -194,7 +194,7 @@ App::get('/console/database') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/database/index.phtml'); @@ -212,7 +212,7 @@ App::get('/console/database/collection') ->inject('layout') ->action(function ($id, $response, $layout) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $logs = new View(__DIR__.'/../../views/console/comps/logs.phtml'); @@ -247,7 +247,7 @@ App::get('/console/database/document') ->param('collection', '', new UID(), 'Collection unique ID.') ->inject('layout') ->action(function ($collection, $layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $logs = new View(__DIR__.'/../../views/console/comps/logs.phtml'); @@ -280,7 +280,7 @@ App::get('/console/database/document/new') ->param('collection', '', new UID(), 'Collection unique ID.') ->inject('layout') ->action(function ($collection, $layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/database/document.phtml'); @@ -301,7 +301,7 @@ App::get('/console/storage') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/storage/index.phtml'); $page @@ -351,7 +351,7 @@ App::get('/console/users') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/users/index.phtml'); @@ -372,7 +372,7 @@ App::get('/console/users/user') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/users/user.phtml'); @@ -387,7 +387,7 @@ App::get('/console/users/teams/team') ->label('scope', 'console') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/console/users/team.phtml'); diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index 59d03a033c..97389b894b 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -3,15 +3,15 @@ use Appwrite\Specification\Format\OpenAPI3; use Appwrite\Specification\Format\Swagger2; use Appwrite\Specification\Specification; +use Appwrite\Utopia\View; use Utopia\App; -use Utopia\View; use Utopia\Config\Config; use Utopia\Exception; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; App::init(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $header = new View(__DIR__.'/../../views/home/comps/header.phtml'); $footer = new View(__DIR__.'/../../views/home/comps/footer.phtml'); @@ -32,7 +32,7 @@ App::init(function ($layout) { App::shutdown(function ($response, $layout) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $response->html($layout->render()); }, ['response', 'layout'], 'home'); @@ -76,7 +76,7 @@ App::get('/auth/signin') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/signin.phtml'); @@ -95,7 +95,7 @@ App::get('/auth/signup') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/signup.phtml'); $page @@ -113,7 +113,7 @@ App::get('/auth/recovery') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/recovery.phtml'); @@ -132,7 +132,7 @@ App::get('/auth/confirm') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/confirm.phtml'); @@ -147,7 +147,7 @@ App::get('/auth/join') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/join.phtml'); @@ -162,7 +162,7 @@ App::get('/auth/recovery/reset') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/recovery/reset.phtml'); @@ -177,7 +177,7 @@ App::get('/auth/oauth2/success') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/oauth2.phtml'); @@ -195,7 +195,7 @@ App::get('/auth/magic-url') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/magicURL.phtml'); @@ -213,7 +213,7 @@ App::get('/auth/oauth2/failure') ->label('scope', 'home') ->inject('layout') ->action(function ($layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/home/auth/oauth2.phtml'); @@ -232,7 +232,7 @@ App::get('/error/:code') ->param('code', null, new \Utopia\Validator\Numeric(), 'Valid status code number', false) ->inject('layout') ->action(function ($code, $layout) { - /** @var Utopia\View $layout */ + /** @var Appwrite\Utopia\View $layout */ $page = new View(__DIR__.'/../../views/error.phtml'); diff --git a/app/init.php b/app/init.php index 87310d4a27..9d966a90a3 100644 --- a/app/init.php +++ b/app/init.php @@ -27,8 +27,8 @@ use Appwrite\Network\Validator\IP; use Appwrite\Network\Validator\URL; use Appwrite\OpenSSL\OpenSSL; use Appwrite\Stats\Stats; +use Appwrite\Utopia\View; use Utopia\App; -use Utopia\View; use Utopia\Config\Config; use Utopia\Locale\Locale; use Utopia\Registry\Registry; @@ -76,8 +76,8 @@ const APP_STORAGE_FUNCTIONS = '/storage/functions'; const APP_STORAGE_CACHE = '/storage/cache'; const APP_STORAGE_CERTIFICATES = '/storage/certificates'; const APP_STORAGE_CONFIG = '/storage/config'; -const APP_SOCIAL_TWITTER = 'https://twitter.com/appwrite_io'; -const APP_SOCIAL_TWITTER_HANDLE = 'appwrite_io'; +const APP_SOCIAL_TWITTER = 'https://twitter.com/appwrite'; +const APP_SOCIAL_TWITTER_HANDLE = 'appwrite'; const APP_SOCIAL_FACEBOOK = 'https://www.facebook.com/appwrite.io'; const APP_SOCIAL_LINKEDIN = 'https://www.linkedin.com/company/appwrite'; const APP_SOCIAL_INSTAGRAM = 'https://www.instagram.com/appwrite.io'; @@ -86,7 +86,7 @@ const APP_SOCIAL_DISCORD = 'https://appwrite.io/discord'; const APP_SOCIAL_DISCORD_CHANNEL = '564160730845151244'; const APP_SOCIAL_DEV = 'https://dev.to/appwrite'; const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; -const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite'; +const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; // Database Worker Types const DATABASE_TYPE_CREATE_ATTRIBUTE = 'createAttribute'; const DATABASE_TYPE_CREATE_INDEX = 'createIndex'; @@ -290,8 +290,8 @@ Database::addFilter('encrypt', return json_encode([ 'data' => OpenSSL::encrypt($value, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag), 'method' => OpenSSL::CIPHER_AES_128_GCM, - 'iv' => bin2hex($iv), - 'tag' => bin2hex($tag), + 'iv' => \bin2hex($iv), + 'tag' => \bin2hex($tag ?? ''), 'version' => '1', ]); }, diff --git a/app/tasks/install.php b/app/tasks/install.php index 0898ae67c1..979e9b4697 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -5,10 +5,10 @@ global $cli; use Appwrite\Auth\Auth; use Appwrite\Docker\Compose; use Appwrite\Docker\Env; +use Appwrite\Utopia\View; use Utopia\Analytics\GoogleAnalytics; use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\View; use Utopia\Validator\Text; $cli diff --git a/app/tasks/sdks.php b/app/tasks/sdks.php index 1bda881f93..21df0928bc 100644 --- a/app/tasks/sdks.php +++ b/app/tasks/sdks.php @@ -180,7 +180,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ->setShareText('Appwrite is a backend as a service for building web or mobile apps') ->setShareURL('http://appwrite.io') ->setShareTags('JS,javascript,reactjs,angular,ios,android,serverless') - ->setShareVia('appwrite_io') + ->setShareVia('appwrite') ->setWarning($warning) ->setReadme($readme) ->setGettingStarted($gettingStarted) diff --git a/app/views/console/database/collection.phtml b/app/views/console/database/collection.phtml index a8b59e8d4a..e87d5d9f98 100644 --- a/app/views/console/database/collection.phtml +++ b/app/views/console/database/collection.phtml @@ -467,8 +467,8 @@ $logs = $this->getParam('logs', null);
Document Level -

With Document Level permissions, you have granular access control over every document, and users will only be able to access documents for which they have explicit permissions.

-

Document permissions are required in this permission model.

+

With Document Level permissions, you have granular access control over every file. Users will only be able to access documents for which they have explicit permissions.

+

In this permission level, document permissions take precedence and bucket permissions are ignored.

@@ -476,8 +476,8 @@ $logs = $this->getParam('logs', null);
Collection Level -

With Collection Level permissions, you assign permissions once for every document in the collection - users with read access to the collection can see all documents.

-

Collection permissions are required in this permission model, and document permissions are optional.

+

With Collection Level permissions, you assign permissions only once in the collection.

+

In this permission level, permissions assigned to collection takes the precedence and documents permissions are ignored

diff --git a/app/views/console/database/form.phtml b/app/views/console/database/form.phtml index 971e4fa702..4012679024 100644 --- a/app/views/console/database/form.phtml +++ b/app/views/console/database/form.phtml @@ -1,6 +1,6 @@ getParam('collection', null); $collections = $this->getParam('collections', []); diff --git a/app/views/layouts/default.phtml b/app/views/layouts/default.phtml index c6c0de795e..5016ccd8d6 100644 --- a/app/views/layouts/default.phtml +++ b/app/views/layouts/default.phtml @@ -10,7 +10,7 @@ $litespeed = $this->getParam('litespeed', true); $analytics = $this->getParam('analytics', 'UA-26264668-9'); $mode = $this->getParam('mode', ''); $canonical = $this->getParam('canonical', ''); -$image = $this->getParam('image', '/images/logo.png'); +$image = $this->getParam('image', '/images/logo.png'); $locale = $this->getParam('locale', null); $runtimes = $this->getParam('runtimes', null); @@ -53,12 +53,17 @@ if(!empty($platforms)) { + + + + +