From 3352dfb423e329212b497d5083a477c66ab609a4 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 6 Jan 2015 12:36:13 +0100 Subject: [PATCH 01/46] Fix migration patch --- lib/classes/patch/320alpha4b.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/classes/patch/320alpha4b.php b/lib/classes/patch/320alpha4b.php index 91a352df64..32e53b9704 100644 --- a/lib/classes/patch/320alpha4b.php +++ b/lib/classes/patch/320alpha4b.php @@ -81,7 +81,7 @@ class patch_320alpha4b implements patchInterface foreach ($rs as $row) { $user = User_Adapter::getInstance($row['usr_id'], $app); - $feed = $this->get_feed($appbox, $user, $row['pub_restrict'], $row['homelink']); + $feed = $this->get_feed($app, $appbox, $user, $row['pub_restrict'], $row['homelink']); if (! $feed instanceof Feed_Adapter) { continue; @@ -138,7 +138,7 @@ class patch_320alpha4b implements patchInterface } protected static $feeds = array(); - protected function get_feed(appbox $appbox, User_Adapter $user, $pub_restrict, $homelink) + protected function get_feed(Application $app, appbox $appbox, User_Adapter $user, $pub_restrict, $homelink) { $user_key = 'user_' . $user->get_id(); if ($homelink == '1') From e6c5c8e10e9835db1935f7f66f98b7a821e9f907 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 6 Jan 2015 12:54:30 +0100 Subject: [PATCH 02/46] Fix sha1_file perf issue --- lib/classes/media/subdef.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/classes/media/subdef.php b/lib/classes/media/subdef.php index 72668fb1a4..c27b3e4595 100644 --- a/lib/classes/media/subdef.php +++ b/lib/classes/media/subdef.php @@ -212,7 +212,12 @@ class media_subdef extends media_abstract implements cache_cacheableInterface $this->mime = $row['mime']; $this->file = $row['file']; $this->path = p4string::addEndSlash($row['path']); - $this->etag = $row['etag'] !== null ? $row['etag'] : sha1_file($this->get_pathfile()); + $file = new SplFileInfo($this->get_pathfile()); + if ($file->isFile()) { + $this->is_physically_present = true; + + $this->etag = $row['etag'] !== null ? $row['etag'] : md5($file->getMTime()); + } $this->is_substituted = ! ! $row['substit']; $this->subdef_id = (int) $row['subdef_id']; @@ -221,7 +226,6 @@ class media_subdef extends media_abstract implements cache_cacheableInterface if ($row['created_on']) $this->creation_date = new DateTime($row['created_on']); - $this->is_physically_present = true; } elseif ($substitute === false) { throw new Exception_Media_SubdefNotFound($this->name . ' not found'); } @@ -352,7 +356,10 @@ class media_subdef extends media_abstract implements cache_cacheableInterface public function getEtag() { if (!$this->etag && $this->is_physically_present()) { - $this->setEtag(sha1_file($this->get_pathfile())); + $file = new SplFileInfo($this->get_pathfile()); + if ($file->isFile()) { + $this->setEtag(md5($file->getMTime())); + } } return $this->etag; From 2d5390abdebc915b508fd65318820ac0166e52d3 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 7 Jan 2015 17:59:18 +0100 Subject: [PATCH 03/46] removed "showmodaldialog(...)" from javascript (removed from chrome) --- .../Controller/Thesaurus/Thesaurus.php | 24 -- .../thesaurus/new-synonym-dialog.html.twig | 86 ------ templates/web/thesaurus/properties.html.twig | 33 -- templates/web/thesaurus/search.html.twig | 65 ---- templates/web/thesaurus/thesaurus.html.twig | 290 ++++++++++++------ 5 files changed, 195 insertions(+), 303 deletions(-) delete mode 100644 templates/web/thesaurus/new-synonym-dialog.html.twig delete mode 100644 templates/web/thesaurus/search.html.twig diff --git a/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php b/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php index 496e1d3581..7c2f7e1c4e 100644 --- a/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php +++ b/lib/Alchemy/Phrasea/Controller/Thesaurus/Thesaurus.php @@ -40,10 +40,8 @@ class Thesaurus implements ControllerProviderInterface $controllers->match('linkfield2.php', $this->call('linkFieldStep2')); $controllers->match('linkfield3.php', $this->call('linkFieldStep3')); $controllers->match('loadth.php', $this->call('loadThesaurus'))->bind('thesaurus_loadth'); - $controllers->match('newsy_dlg.php', $this->call('newSynonymDialog')); $controllers->match('newterm.php', $this->call('newTerm')); $controllers->match('properties.php', $this->call('properties')); - $controllers->match('search.php', $this->call('search')); $controllers->match('thesaurus.php', $this->call('thesaurus'))->bind('thesaurus_thesaurus'); $controllers->match('xmlhttp/accept.x.php', $this->call('acceptXml')); @@ -1121,23 +1119,6 @@ class Thesaurus implements ControllerProviderInterface )); } - public function newSynonymDialog(Application $app, Request $request) - { - $languages = array(); - - foreach ($app['locales.available'] as $lng_code => $lng) { - $lng_code = explode('_', $lng_code); - $languages[$lng_code[0]] = $lng; - } - - return $app['twig']->render('thesaurus/new-synonym-dialog.html.twig', array( - 'piv' => $request->get('piv'), - 'typ' => $request->get('typ'), - 'languages' => $languages, - )); - } - - public function newTerm(Application $app, Request $request) { list($term, $context) = $this->splitTermAndContext($request->get("t")); @@ -1220,11 +1201,6 @@ class Thesaurus implements ControllerProviderInterface )); } - public function search(Application $app, Request $request) - { - return $app['twig']->render('thesaurus/search.html.twig'); - } - public function thesaurus(Application $app, Request $request) { $flags = $jsFlags = array(); diff --git a/templates/web/thesaurus/new-synonym-dialog.html.twig b/templates/web/thesaurus/new-synonym-dialog.html.twig deleted file mode 100644 index 7a18595bfb..0000000000 --- a/templates/web/thesaurus/new-synonym-dialog.html.twig +++ /dev/null @@ -1,86 +0,0 @@ -{% if 'TS' == typ %} - {% set title = 'thesaurus:: Nouveau terme' | trans %} - {% set label = 'thesaurus:: terme' | trans %} -{% elseif 'SY' == typ %} - {% set title = 'thesaurus:: Nouveau synonyme' | trans %} - {% set label = 'thesaurus:: synonyme' | trans %} -{% else %} - {% set title = '' %} - {% set label = '' %} -{% endif %} - - - - {{ title }} - - - - - - - -
-
- - - - - - - - - - - - - - - - -
{{ label }} : 
{% trans 'thesaurus:: contexte' %} : (  )
{% trans 'phraseanet:: language' %} :  - {% for code, language in languages %} - - - - -    - {% endfor %} -
-
-
- -    - -
-
-
-
- - diff --git a/templates/web/thesaurus/properties.html.twig b/templates/web/thesaurus/properties.html.twig index a71cff8013..12ade717e7 100644 --- a/templates/web/thesaurus/properties.html.twig +++ b/templates/web/thesaurus/properties.html.twig @@ -47,7 +47,6 @@
@@ -193,14 +192,6 @@ document.getElementById("delete_sy").className = ""; } } - // si on ne connait pas encore le client mais que start est ouvert, on lui demande - // if(!opener.wClient && opener.opener.wClient) - // opener.wClient = opener.opener.wClient; - // si on connait le client et qu'on peut s'en servir pour chercher, on active l'option dans le menu - // if(opener.wClient && opener.wClient.externQuery) - // document.getElementById("searchcli_sy").className = ""; - // else - // document.getElementById("searchcli_sy").className = "disabled"; return; } @@ -250,30 +241,6 @@ } } break; - case "searchcli_sy": // cbParm = objet 'TR' - url = "xmlhttp/getsy.x.php"; - url += "?bid={{ bid | url_encode }}"; - url += "&id=" + cbParm.id.substr(4); - url += "&typ={{ typ | url_encode }}"; - ret = loadXMLDoc(url, null, true); - t = ret.getElementsByTagName("sy").item(0).getAttribute("t"); - - if(opener.wClient && opener.wClient.externQuery) - { - opener.wClient.focus(); - opener.wClient.externQuery(opener.currentBaseId, t); - } - - break; - case "replace_sy": - url = "replace.php"; - url += "?bid={{ bid }}"; - url += "&piv={{ piv }}"; - url += "&pid={{ id }}" - url += "&id=" + o.id.substr(4); - url += "&typ={{ typ | url_encode }}"; - w = window.open(url, "REPLACE", "directories=no, height=300, width=500, location=no, menubar=no, resizable=yes, scrollbars=yes, status=no, toolbar=no"); - break; } } diff --git a/templates/web/thesaurus/search.html.twig b/templates/web/thesaurus/search.html.twig deleted file mode 100644 index 5c52ba1c2e..0000000000 --- a/templates/web/thesaurus/search.html.twig +++ /dev/null @@ -1,65 +0,0 @@ - - - - - {% trans 'Chercher' %} - - - - -
-
-
-
- - - - - - - - - - - -
{% trans 'thesaurus:: le terme' %}{% trans 'thesaurus:: est egal a ' %}
- {% trans 'thesaurus:: commence par' %}
- {% trans 'thesaurus:: contient' %}
-
- -
-
-
- -     - -
-
- - diff --git a/templates/web/thesaurus/thesaurus.html.twig b/templates/web/thesaurus/thesaurus.html.twig index c32e70b53c..4459a200a1 100644 --- a/templates/web/thesaurus/thesaurus.html.twig +++ b/templates/web/thesaurus/thesaurus.html.twig @@ -9,6 +9,8 @@ display: none; } + + + {% endif %} {% set ratio = app['authentication'].getUser().getPrefs('search_window') %} {% if ratio == 0 %} {% set ratio = '0.333' %} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php index 0ee6efcd7c..c343938067 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php @@ -2,8 +2,6 @@ namespace Alchemy\Tests\Phrasea\Controller\Client; -use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; - class RootTest extends \PhraseanetWebTestCaseAuthenticatedAbstract { protected $client; @@ -25,57 +23,6 @@ class RootTest extends \PhraseanetWebTestCaseAuthenticatedAbstract { $this->authenticate(self::$DI['app']); self::$DI['client']->request("GET", "/client/"); - $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - } - - /** - * @covers Alchemy\Phrasea\Controller\Client\Root::getClientLanguage - */ - public function testGetLanguage() - { - self::$DI['client']->request("GET", "/client/language/"); - $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - } - - /** - * @covers Alchemy\Phrasea\Controller\Client\Root::getClientPublications - */ - public function testGetPublications() - { - self::$DI['client']->request("GET", "/client/publications/"); - $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - } - - /** - * @covers Alchemy\Phrasea\Controller\Client\Root::getClientHelp - */ - public function testGetClientHelp() - { - self::$DI['client']->request("GET", "/client/help/"); - $this->assertTrue(self::$DI['client']->getResponse()->isOk()); - } - - /** - * @covers Alchemy\Phrasea\Controller\Client\Root::query - * @covers Alchemy\Phrasea\Controller\Client\Root::buildQueryFromRequest - */ - public function testExecuteQuery() - { - $queryParameters = array(); - $queryParameters["mod"] = self::$DI['user']->getPrefs('client_view') ? : '3X6'; - $queryParameters["bas"] = array_keys(self::$DI['user']->ACL()->get_granted_base()); - $queryParameters["qry"] = self::$DI['user']->getPrefs('start_page_query') ? : 'all'; - $queryParameters["pag"] = 0; - $queryParameters["search_type"] = SearchEngineOptions::RECORD_RECORD; - $queryParameters["qryAdv"] = ''; - $queryParameters["opAdv"] = array(); - $queryParameters["status"] = array(); - $queryParameters["recordtype"] = SearchEngineOptions::TYPE_ALL; - $queryParameters["sort"] = self::$DI['app']['phraseanet.registry']->get('GV_phrasea_sort', ''); - $queryParameters["infield"] = array(); - $queryParameters["ord"] = SearchEngineOptions::SORT_MODE_DESC; - - self::$DI['client']->request("POST", "/client/query/", $queryParameters); - $this->assertTrue(self::$DI['client']->getResponse()->isOk()); + $this->assertTrue(self::$DI['client']->getResponse()->isRedirect()); } } diff --git a/www/skins/prod/000000/prodcolor.css b/www/skins/prod/000000/prodcolor.css index f54b6b8eb8..4141df63de 100644 --- a/www/skins/prod/000000/prodcolor.css +++ b/www/skins/prod/000000/prodcolor.css @@ -4253,3 +4253,11 @@ ui-dialog-titlebar { position: relative; float: left; } + +#clientModal, #clientModal .modal-footer { + background-color: #404040; +} + +#clientModal .close { + color: #fff; +} diff --git a/www/skins/prod/959595/prodcolor.css b/www/skins/prod/959595/prodcolor.css index 94aa87bb55..7b3eab5a5a 100644 --- a/www/skins/prod/959595/prodcolor.css +++ b/www/skins/prod/959595/prodcolor.css @@ -4376,3 +4376,12 @@ ui-dialog-titlebar { position: relative; float: left; } + +#clientModal, #clientModal .modal-footer { + background-color: #999999; + color: #fff; +} + +#clientModal .close { + color: #404040; +} From a60968541772a01e0df4cc5fe430160a389711aa Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 15:31:00 +0100 Subject: [PATCH 17/46] PHRAS-343 Disabled record type when choosing story search mode --- lib/Alchemy/Phrasea/Controller/Client/Root.php | 2 +- templates/web/prod/index.html.twig | 4 ++-- .../Tests/Phrasea/Controller/Client/RootTest.php | 13 ------------- www/skins/prod/jquery.main-prod.js | 10 ++++++++++ 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Client/Root.php b/lib/Alchemy/Phrasea/Controller/Client/Root.php index 2ef659f89e..da2c1c4f04 100644 --- a/lib/Alchemy/Phrasea/Controller/Client/Root.php +++ b/lib/Alchemy/Phrasea/Controller/Client/Root.php @@ -34,7 +34,7 @@ class Root implements ControllerProviderInterface * * Redirect to production with a nice message */ - $app['session']->getFlashBag()->add('client_deprecated'); + $app['session']->getFlashBag()->add('client_deprecated', ''); return $app->redirectPath('prod'); diff --git a/templates/web/prod/index.html.twig b/templates/web/prod/index.html.twig index 0132e12d8d..3e2d271124 100644 --- a/templates/web/prod/index.html.twig +++ b/templates/web/prod/index.html.twig @@ -303,11 +303,11 @@
{% if GV_multiAndReport %} {% else %} diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php index c343938067..b1734e998b 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Client/RootTest.php @@ -6,19 +6,6 @@ class RootTest extends \PhraseanetWebTestCaseAuthenticatedAbstract { protected $client; - /** - * @covers Alchemy\Phrasea\Controller\Client\Root::connect - * @covers Alchemy\Phrasea\Controller\Client\Root::call - * @covers Alchemy\Phrasea\Controller\Client\Root::getClient - * @covers Alchemy\Phrasea\Controller\Client\Root::getDefaultClientStartPage - * @covers Alchemy\Phrasea\Controller\Client\Root::getQueryStartPage - * @covers Alchemy\Phrasea\Controller\Client\Root::getHelpStartPage - * @covers Alchemy\Phrasea\Controller\Client\Root::getPublicationStartPage - * @covers Alchemy\Phrasea\Controller\Client\Root::getGridProperty - * @covers Alchemy\Phrasea\Controller\Client\Root::getDocumentStorageAccess - * @covers Alchemy\Phrasea\Controller\Client\Root::getTabSetup - * @covers Alchemy\Phrasea\Controller\Client\Root::getCssFile - */ public function testGetClient() { $this->authenticate(self::$DI['app']); diff --git a/www/skins/prod/jquery.main-prod.js b/www/skins/prod/jquery.main-prod.js index 028939b7dc..25a2689b88 100644 --- a/www/skins/prod/jquery.main-prod.js +++ b/www/skins/prod/jquery.main-prod.js @@ -756,6 +756,16 @@ function HueToRgb(m1, m2, hue) { $(document).ready(function () { + $('input[name=search_type]').bind('click', function () { + var $this = $(this); + var $record_types = $('#recordtype_sel'); + if ($this.hasClass('mode_type_reg')) { + $record_types.attr('disabled', true); + } else { + $record_types.removeAttr('disabled'); + } + }); + $('.adv_search_button').live('click', function () { var searchForm = $('#searchForm'); var parent = searchForm.parent(); From 87dbd0150d73bf842f59a5d88a21ea2e5e8ef1e6 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 15:49:28 +0100 Subject: [PATCH 18/46] PHRAS-359 Allow to apply model to a model --- lib/Alchemy/Phrasea/Helper/User/Edit.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/Alchemy/Phrasea/Helper/User/Edit.php b/lib/Alchemy/Phrasea/Helper/User/Edit.php index 9e87c6f84e..69c5260fbd 100644 --- a/lib/Alchemy/Phrasea/Helper/User/Edit.php +++ b/lib/Alchemy/Phrasea/Helper/User/Edit.php @@ -657,10 +657,6 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper foreach ($this->users as $usr_id) { $user = \User_adapter::getInstance($usr_id, $this->app); - if ($user->is_template()) { - continue; - } - $user->ACL()->apply_model($template, $base_ids); } From 0275ede43cbaa80471d408be28ef512081de778e Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 16:00:01 +0100 Subject: [PATCH 19/46] PHRAS-315 Do not expose not downloadable subdef --- lib/classes/API/V1/adapter.php | 12 ++++++++++++ .../Tests/Phrasea/Application/ApiAbstract.php | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/classes/API/V1/adapter.php b/lib/classes/API/V1/adapter.php index c81470510e..432a9221b7 100644 --- a/lib/classes/API/V1/adapter.php +++ b/lib/classes/API/V1/adapter.php @@ -1460,6 +1460,7 @@ class API_V1_adapter extends API_V1_Abstract return null; } + if ($this->app['authentication']->isAuthenticated()) { if ($media->get_name() !== 'document' && false === $this->app['authentication']->getUser()->ACL()->has_access_to_subdef($record, $media->get_name())) { return null; @@ -1470,6 +1471,17 @@ class API_V1_adapter extends API_V1_Abstract } } + $databox = $record->get_databox(); + try { + $subDefDefinition = $databox->get_subdef_structure()->get_subdef($record->get_type(), $media->get_name()); + } catch (Exception_Databox_SubdefNotFound $e) { + return null; + } + + if (false === $subDefDefinition->is_downloadable()) { + return null; + } + if ($media->get_permalink() instanceof media_Permalink_Adapter) { $permalink = $this->list_permalink($media->get_permalink(), $registry); } else { diff --git a/tests/Alchemy/Tests/Phrasea/Application/ApiAbstract.php b/tests/Alchemy/Tests/Phrasea/Application/ApiAbstract.php index 05308b48d1..9eba7fc22f 100644 --- a/tests/Alchemy/Tests/Phrasea/Application/ApiAbstract.php +++ b/tests/Alchemy/Tests/Phrasea/Application/ApiAbstract.php @@ -1067,7 +1067,6 @@ abstract class ApiAbstract extends \PhraseanetWebTestCaseAbstract $embedTypes = array_flip(array_map(function($subdef) {return $subdef['name'];},$content['response']['embed'])); //access to all subdefs - $this->assertArrayHasKey('document', $embedTypes); $this->assertArrayHasKey('preview', $embedTypes); $this->assertArrayHasKey('thumbnail', $embedTypes); From 99bc7d0e657a4ff7ff0e1dcfdc72e8ffcf4192b6 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 16:42:38 +0100 Subject: [PATCH 20/46] PHRAS-288 Check if storage engines is available --- lib/Alchemy/Phrasea/Command/Setup/Install.php | 5 +++++ .../Phrasea/Controller/Admin/Databoxes.php | 12 +++++++++++ lib/Alchemy/Phrasea/Helper/DatabaseHelper.php | 7 +++++-- lib/classes/connection/abstract.php | 21 +++++++++++++++++++ lib/classes/databox.php | 4 ++++ templates/web/setup/step2.html.twig | 7 ++++++- 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/Setup/Install.php b/lib/Alchemy/Phrasea/Command/Setup/Install.php index 7bacd51010..6be7bfa4f5 100644 --- a/lib/Alchemy/Phrasea/Command/Setup/Install.php +++ b/lib/Alchemy/Phrasea/Command/Setup/Install.php @@ -92,6 +92,11 @@ class Install extends Command } $abConn = $this->getABConn($input, $output, $dialog); + + if (false === $abConn->supportInnoDB()){ + throw new \Exception('Database server does not support InnoDB storage engine'); + } + list($dbConn, $template) = $this->getDBConn($input, $output, $abConn, $dialog); list($email, $password) = $this->getCredentials($input, $output, $dialog); $dataPath = $this->getDataPath($input, $output, $dialog); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php b/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php index 71215a19d1..7908ea0221 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Databoxes.php @@ -178,6 +178,9 @@ class Databoxes implements ControllerProviderInterface case 'mount-failed' : $errorMsg = _('Database could not be mounted'); break; + case 'innodb-support' : + $errorMsg = _('Database server does not support InnoDB storage engine'); + break; } $upgrader = new \Setup_Upgrade($app); @@ -228,6 +231,10 @@ class Databoxes implements ControllerProviderInterface return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'database-failed')); } + if (false === $connbas->supportInnoDB()){ + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'innodb-support')); + } + try { $base = \databox::create($app, $connbas, $dataTemplate, $app['phraseanet.registry']); $base->registerAdmin($app['authentication']->getUser()); @@ -250,6 +257,11 @@ class Databoxes implements ControllerProviderInterface try { $data_template = new \SplFileInfo($app['root.path'] . '/lib/conf.d/data_templates/' . $dataTemplate . '.xml'); $connbas = new \connection_pdo('databox_creation', $hostname, $port, $userDb, $passwordDb, $dbName, array(), $app['debug']); + + if (false === $connbas->supportInnoDB()){ + return $app->redirectPath('admin_databases', array('success' => 0, 'error' => 'innodb-support')); + } + try { $base = \databox::create($app, $connbas, $data_template, $app['phraseanet.registry']); $base->registerAdmin($app['authentication']->getUser()); diff --git a/lib/Alchemy/Phrasea/Helper/DatabaseHelper.php b/lib/Alchemy/Phrasea/Helper/DatabaseHelper.php index f70887a463..3689beff0e 100644 --- a/lib/Alchemy/Phrasea/Helper/DatabaseHelper.php +++ b/lib/Alchemy/Phrasea/Helper/DatabaseHelper.php @@ -23,10 +23,12 @@ class DatabaseHelper extends Helper $password = $this->request->query->get('password'); $db_name = $this->request->query->get('db_name'); - $connection_ok = $db_ok = $is_databox = $is_appbox = $empty = false; + $connection_ok = $innodb = $db_ok = $is_databox = $is_appbox = $empty = false; try { - new \connection_pdo('test', $hostname, $port, $user, $password, $db_name, array(), false); + $conn = new \connection_pdo('test', $hostname, $port, $user, $password, $db_name, array(), false); + $innodb = $conn->supportInnoDB(); + $connection_ok = true; } catch (\Exception $e) { @@ -61,6 +63,7 @@ class DatabaseHelper extends Helper return array( 'connection' => $connection_ok, + 'innodb' => $innodb, 'database' => $db_ok, 'is_empty' => $empty, 'is_appbox' => $is_appbox, diff --git a/lib/classes/connection/abstract.php b/lib/classes/connection/abstract.php index 26acddd415..3b49286a74 100644 --- a/lib/classes/connection/abstract.php +++ b/lib/classes/connection/abstract.php @@ -59,6 +59,27 @@ abstract class connection_abstract return $this->connection->getAttribute(constant("PDO::ATTR_SERVER_VERSION")); } + public function supportInnoDB() + { + if (false === $this->ping()) { + throw new \Exception('Mysql server is not reachable'); + } + + $stmt = $this->connection->query('SHOW ENGINES'); + $stmt->execute(); + $engines = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + foreach ($engines as $engine) { + if (strtolower($engine['Engine']) !== 'innodb') { + continue; + } + + return $engine['Support'] !== 'NO'; + } + + return false; + } + public function __destruct() { $this->close(); diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 7bea4f31b5..96a18ff422 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -618,6 +618,10 @@ class databox extends base { $connection = new connection_pdo('test', $host, $port, $user, $password, $dbname, array(), $app['debug']); + if (false === $connection->supportInnoDB()) { + throw new \Exception('Database server does not support InnoDB storage engine'); + } + $conn = $app['phraseanet.appbox']->get_connection(); $sql = 'SELECT MAX(ord) as ord FROM sbas'; $stmt = $conn->prepare($sql); diff --git a/templates/web/setup/step2.html.twig b/templates/web/setup/step2.html.twig index 02390cd383..017c887c65 100644 --- a/templates/web/setup/step2.html.twig +++ b/templates/web/setup/step2.html.twig @@ -211,7 +211,7 @@ }, success: function (data) { el_loader.css('visibility', 'hidden'); - if (data.connection === true && data.database === true) { + if (data.connection === true && data.database === true && data.innodb === true) { el_status.attr('src', '/skins/icons/ok.png').show(); el_message.empty().append("{% trans 'Successfull connection' %}"); if (!data.is_empty) { @@ -223,6 +223,11 @@ return; } + if (false === data.innodb) { + el_message.empty().append("{% trans 'Database server does not support InnoDB storage engine' %}"); + + return; + } if (data.connection === true) { el_message.empty().append("{% trans 'Connection is OK but database does not exists or can not be accessed' %}"); } else { From b118d4d9475ff7eefb66a73e8ce354d6bb90f2b8 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 17:01:12 +0100 Subject: [PATCH 21/46] PHRAS-285 Fix default field focus --- templates/web/admin/fields/templates.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/web/admin/fields/templates.html.twig b/templates/web/admin/fields/templates.html.twig index 8bad226ce3..66e46bc664 100644 --- a/templates/web/admin/fields/templates.html.twig +++ b/templates/web/admin/fields/templates.html.twig @@ -96,7 +96,7 @@ <% _.each(field.labels, function(value, code) { %> - > + > <% }); %> From 058fcfce06a5f54d7a4ed33b34974313dc376499 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 17:17:31 +0100 Subject: [PATCH 22/46] PHRAS-284 Fix javascript issue --- templates/web/report/report_layout_child.html.twig | 12 ++++++------ www/skins/report/report.js | 7 ++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/templates/web/report/report_layout_child.html.twig b/templates/web/report/report_layout_child.html.twig index d871c098bd..89227c68d8 100644 --- a/templates/web/report/report_layout_child.html.twig +++ b/templates/web/report/report_layout_child.html.twig @@ -178,12 +178,12 @@
- + + + + +
diff --git a/www/skins/report/report.js b/www/skins/report/report.js index ffce467cb6..ffa7c102d0 100644 --- a/www/skins/report/report.js +++ b/www/skins/report/report.js @@ -74,9 +74,14 @@ function bindEvents() { loadDash(); }); //load all the report - $('form .formsubmiter').bind('click', function () { + $('form input.formsubmiter').bind('click', function () { submiterAction($(this)); }); + + $('form select.formsubmiter').bind('change', function () { + submiterAction($("option:selected", $(this))); + }); + //reload the content by pressing enter key, it concerns the number of result by report $('form .entersubmiter').bind('keypress', function (event) { if (event.keyCode == '13') { From 8fc8a2ac88ec7ea7dafc6a220fb7286170223bbb Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 17:52:51 +0100 Subject: [PATCH 23/46] PHRAS-260 Remove collection banner --- .../Phrasea/Controller/Admin/Collection.php | 119 ------------------ .../web/admin/collection/collection.html.twig | 9 -- .../Controller/Admin/AdminCollectionTest.php | 59 --------- 3 files changed, 187 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php b/lib/Alchemy/Phrasea/Controller/Admin/Collection.php index 3b0b870744..1ab8e0cd85 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Collection.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Collection.php @@ -325,40 +325,6 @@ class Collection implements ControllerProviderInterface ->assert('bas_id', '\d+') ->bind('admin_collection_delete_stamp'); - /** - * Set a new banner - * - * name : admin_collection_submit_banner - * - * description : Set a new logo - * - * method : POST - * - * parameters : none - * - * return : REDIRECT Response - */ - $controllers->post('/{bas_id}/picture/banner/', $this->call('setBanner')) - ->assert('bas_id', '\d+') - ->bind('admin_collection_submit_banner'); - - /** - * Delete a banner - * - * name : admin_collection_delete_banner - * - * description : Delete a mini logo - * - * method : POST - * - * parameters : none - * - * return : REDIRECT Response - */ - $controllers->post('/{bas_id}/picture/banner/delete/', $this->call('deleteBanner')) - ->assert('bas_id', '\d+') - ->bind('admin_collection_delete_banner'); - /** * Get document details in the requested collection * @@ -523,41 +489,6 @@ class Collection implements ControllerProviderInterface )); } - /** - * Delete the collection banner - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return JsonResponse|RedirectResponse - */ - public function deleteBanner(Application $app, Request $request, $bas_id) - { - $success = false; - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, null, \collection::PIC_PRESENTATION); - $success = true; - } catch (\Exception $e) { - - } - - if ('json' === $app['request']->getRequestFormat()) { - return $app->json(array( - 'success' => $success, - 'msg' => $success ? _('Successful removal') : _('An error occured'), - 'bas_id' => $collection->get_base_id() - )); - } - - return $app->redirectPath('admin_display_collection', array( - 'bas_id' => $collection->get_base_id(), - 'success' => (int) $success, - )); - } - /** * Delete the collection stamp * @@ -664,56 +595,6 @@ class Collection implements ControllerProviderInterface )); } - /** - * Set a collection banner - * - * @param Application $app The silex application - * @param Request $request The current request - * @param integer $bas_id The collection base_id - * @return RedirectResponse - */ - public function setBanner(Application $app, Request $request, $bas_id) - { - if (null === $file = $request->files->get('newBanner')) { - $app->abort(400); - } - - if ($file->getClientSize() > 1024 * 1024) { - return $app->redirectPath('admin_display_collection', array( - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-too-big', - )); - } - - if (!$file->isValid()) { - return $app->redirectPath('admin_display_collection', array( - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-invalid', - )); - } - - $collection = \collection::get_from_base_id($app, $bas_id); - - try { - $app['phraseanet.appbox']->write_collection_pic($app['media-alchemyst'], $app['filesystem'], $collection, $file, \collection::PIC_PRESENTATION); - - $app['filesystem']->remove($file->getPathname()); - } catch (\Exception $e) { - return $app->redirectPath('admin_display_collection', array( - 'bas_id' => $bas_id, - 'success' => 0, - 'error' => 'file-error', - )); - } - - return $app->redirectPath('admin_display_collection', array( - 'bas_id' => $bas_id, - 'success' => 1, - )); - } - /** * Set a collection stamp * diff --git a/templates/web/admin/collection/collection.html.twig b/templates/web/admin/collection/collection.html.twig index 4a681cc3cc..020ae778b8 100644 --- a/templates/web/admin/collection/collection.html.twig +++ b/templates/web/admin/collection/collection.html.twig @@ -226,15 +226,6 @@ {% endif%} - {% elseif app['authentication'].getUser().ACL.has_right_on_base(bas_id, 'manage') %} - {% trans 'admin::base:collection: aucun fichier (minilogo, watermark ...)' %} -
- - - {% trans %}Select files...{% endtrans %} - - -
{% endif %}
diff --git a/tests/Alchemy/Tests/Phrasea/Controller/Admin/AdminCollectionTest.php b/tests/Alchemy/Tests/Phrasea/Controller/Admin/AdminCollectionTest.php index e07e696b50..8bc4c61d63 100644 --- a/tests/Alchemy/Tests/Phrasea/Controller/Admin/AdminCollectionTest.php +++ b/tests/Alchemy/Tests/Phrasea/Controller/Admin/AdminCollectionTest.php @@ -615,17 +615,6 @@ class AdminCollectionTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $this->assertBadResponse(self::$DI['client']->getResponse()); } - /** - * @covers Alchemy\Phrasea\Controller\Admin\Bas::setBanner - */ - public function testSetBannerBadRequest() - { - $this->setAdmin(true); - - self::$DI['client']->request('POST', '/admin/collection/' . self::$DI['collection']->get_base_id() . '/picture/banner/'); - - $this->assertBadResponse(self::$DI['client']->getResponse()); - } /** * @covers Alchemy\Phrasea\Controller\Admin\Bas::setMiniLogo @@ -769,54 +758,6 @@ class AdminCollectionTest extends \PhraseanetWebTestCaseAuthenticatedAbstract $this->assertTrue($json->success); } - /** - * @covers Alchemy\Phrasea\Controller\Admin\Bas::setBanner - */ - public function testSetBanner() - { - $this->setAdmin(true); - - $target = tempnam(sys_get_temp_dir(), 'p4logo') . '.jpg'; - self::$DI['app']['filesystem']->copy(__DIR__ . '/../../../../../files/p4logo.jpg', $target); - $files = array( - 'newBanner' => new \Symfony\Component\HttpFoundation\File\UploadedFile($target, 'logo.jpg') - ); - self::$DI['client']->request('POST', '/admin/collection/' . self::$DI['collection']->get_base_id() . '/picture/banner/', array(), $files); - $this->checkRedirection(self::$DI['client']->getResponse(), '/admin/collection/' . self::$DI['collection']->get_base_id() . '/?success=1'); - $this->assertEquals(1, count(\collection::getPresentation(self::$DI['collection']->get_base_id()))); - } - - /** - * @covers Alchemy\Phrasea\Controller\Admin\Bas::deleteBanner - */ - public function testDeleteBannerNotJson() - { - $this->setAdmin(true); - - $collection = $this->createOneCollection(); - - self::$DI['client']->request('POST', '/admin/collection/' . $collection->get_base_id() . '/picture/banner/delete/'); - - $this->assertTrue(self::$DI['client']->getResponse()->isRedirect()); - } - - /** - * @covers Alchemy\Phrasea\Controller\Admin\Bas::deleteBanner - */ - public function testDeleteBanner() - { - if (count(\collection::getPresentation(self::$DI['collection']->get_base_id())) === 0) { - $this->markTestSkipped('No Banner setted'); - } - - $this->setAdmin(true); - - $this->XMLHTTPRequest('POST', '/admin/collection/' . self::$DI['collection']->get_base_id() . '/picture/banner/delete/'); - - $json = $this->getJson(self::$DI['client']->getResponse()); - $this->assertTrue($json->success); - } - /** * @covers Alchemy\Phrasea\Controller\Admin\Bas::getCollection */ From 12a8de065fdbdff48346597a124932e2709d95c4 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Mon, 12 Jan 2015 18:49:34 +0100 Subject: [PATCH 24/46] PHRAS-147 Fix javascript issue for suggested values --- .../collection/suggested_value.html.twig | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/templates/web/admin/collection/suggested_value.html.twig b/templates/web/admin/collection/suggested_value.html.twig index d3d3d4c7cc..f0d241bc9a 100644 --- a/templates/web/admin/collection/suggested_value.html.twig +++ b/templates/web/admin/collection/suggested_value.html.twig @@ -427,23 +427,24 @@ function desactiv4VS() if( o2.length > 0 ) { - var optionLength = o2.find("options").length; - if ( optionLength > 1) { + var optionLength = o2.find("option").length; + var index = o2.prop("selectedIndex"); - if ((o2.prop("selectedIndex")+1) != optionLength) { + if ( optionLength > 1) { + if ((index+1) == optionLength) { activer_bout('bout_desc',false); } else { activer_bout('bout_desc',true); } - if (o2.prop("selectedIndex")!=0 && optionLength>1) { + if (index == 0 && optionLength>1) { activer_bout('bout_mont',false); } else { activer_bout('bout_mont',true); } } else { - activer_bout('bout_desc',true); - activer_bout('bout_mont',true); + activer_bout('bout_desc',false); + activer_bout('bout_mont',false); } } @@ -461,7 +462,7 @@ function activ4VS() } desactiv4VS(); - activer_bout('bout_supp',false); + activer_bout('bout_supp',true); } // supprime une valsug @@ -516,7 +517,7 @@ function supprimer() } if(o2.prop("selectedIndex")<0) { - activer_bout('bout_supp',true); + activer_bout('bout_supp',false); } desactiv4VS(); @@ -766,7 +767,11 @@ function activer_bout(idBout,val) o = $("#"+idBout); if( o.length > 0 ) { - o.attr("disabled", val); + if (!val) { + o.attr("disabled", true); + } else { + o.removeAttr("disabled"); + } } } From 89897ed30224d0b6d29b7fe67fa162fa6de83e3b Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 13 Jan 2015 13:41:39 +0100 Subject: [PATCH 25/46] PHRAS-276 Add expiration date for password renewal link in email --- lib/Alchemy/Phrasea/Controller/Root/Login.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index 77bb89d835..950b1c88d4 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -659,7 +659,8 @@ class Login implements ControllerProviderInterface throw new FormProcessingException(_('Invalid email address')); } - $token = $app['tokens']->getUrlToken(\random::TYPE_PASSWORD, $user->get_id(), new \DateTime('+1 day')); + $expirationDate = new \DateTime('+1 day'); + $token = $app['tokens']->getUrlToken(\random::TYPE_PASSWORD, $user->get_id(), $expirationDate); if (!$token) { return $app->abort(500, 'Unable to generate a token'); @@ -670,6 +671,7 @@ class Login implements ControllerProviderInterface $mail = MailRequestPasswordUpdate::create($app, $receiver); $mail->setLogin($user->get_login()); $mail->setButtonUrl($url); + $mail->setExpiration($expirationDate); $app['notification.deliverer']->deliver($mail); $app->addFlash('info', _('phraseanet:: Un email vient de vous etre envoye')); From 5ceb6a86458a397d9dfa78dd0f9ee30ebd0dcea0 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 13 Jan 2015 16:37:27 +0100 Subject: [PATCH 26/46] PHRAS-372 Allow user to change mime type of a record --- .../Phrasea/Controller/Prod/Property.php | 9 +++++- lib/classes/record/adapter.php | 28 ++++++++++++++++++- .../web/prod/actions/Property/type.html.twig | 5 ++-- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Property.php b/lib/Alchemy/Phrasea/Controller/Prod/Property.php index 1cd991b716..925a6485a1 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Property.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Property.php @@ -244,6 +244,7 @@ class Property implements ControllerProviderInterface public function changeType(Application $app, Request $request) { $typeLst = $request->request->get('types', array()); + $mimeLst = $request->request->get('mimes', array()); $records = RecordsRequest::fromRequest($app, $request, false, array('canmodifrecord')); $forceType = $request->request->get('force_types', ''); $updated = array(); @@ -251,10 +252,16 @@ class Property implements ControllerProviderInterface foreach ($records as $record) { try { $recordType = !empty($forceType) ? $forceType : (isset($typeLst[$record->get_serialize_key()]) ? $typeLst[$record->get_serialize_key()] : null); + $mimeType = isset($mimeLst[$record->get_serialize_key()]) ? $mimeLst[$record->get_serialize_key()] : null; if ($recordType) { $record->set_type($recordType); - $updated[$record->get_serialize_key()] = $recordType; + $updated[$record->get_serialize_key()]['record_type'] = $recordType; + } + + if ($mimeType) { + $record->set_mime($mimeType); + $updated[$record->get_serialize_key()]['mime_type'] = $mimeType; } } catch (\Exception $e) { diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php index 03ebc4bde4..d2a0b6a81c 100644 --- a/lib/classes/record/adapter.php +++ b/lib/classes/record/adapter.php @@ -319,6 +319,32 @@ class record_adapter implements record_Interface, cache_cacheableInterface return $this; } + public function set_mime($mime) + { + $old_mime = $this->get_mime(); + + // see http://lists.w3.org/Archives/Public/xml-dist-app/2003Jul/0064.html + if (!preg_match("/^[a-zA-Z0-9!#$%^&\*_\-\+{}\|'.`~]+\/[a-zA-Z0-9!#$%^&\*_\-\+{}\|'.`~]+$/", $mime)) { + throw new \Exception(sprintf('Unrecognized mime type %s', $mime)); + } + + $connection = connection::getPDOConnection($this->app, $this->get_sbas_id()); + + $sql = 'UPDATE record SET mime = :mime WHERE record_id = :record_id'; + $stmt = $connection->prepare($sql); + $stmt->execute(array(':mime' => $mime, ':record_id' => $this->get_record_id())); + $stmt->closeCursor(); + + if ($mime !== $old_mime) { + $this->rebuild_subdefs(); + } + + $this->mime = $mime; + $this->delete_data_from_cache(); + + return $this; + } + /** * Return true if the record is a grouping * @@ -1176,7 +1202,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface * * @return record_adapter */ - public function rebuild_subdefs() + public function rebuild_subdefs() { $connbas = connection::getPDOConnection($this->app, $this->get_sbas_id()); $sql = 'UPDATE record SET jeton=(jeton | ' . JETON_MAKE_SUBDEF . ') WHERE record_id = :record_id'; diff --git a/templates/web/prod/actions/Property/type.html.twig b/templates/web/prod/actions/Property/type.html.twig index 591db4ead2..e58827087b 100644 --- a/templates/web/prod/actions/Property/type.html.twig +++ b/templates/web/prod/actions/Property/type.html.twig @@ -28,13 +28,14 @@
{{ thumbnail.format(record.get_thumbnail(), 160, 120, "", false, false) }}
-
{{ record.get_title() }}
+
{{ record.get_title() }}

- {% for option in typesEnum %} {% endfor %} +

From e43036aaf18755d3ee1e54d2a83f3aed07860c62 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Wed, 14 Jan 2015 16:33:17 +0100 Subject: [PATCH 27/46] PHRAS-316 Fix animated gif delay --- composer.json | 2 +- composer.lock | 38 ++++++++++++++++++-------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index 4df120ba25..7f896af3f3 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "jms/serializer" : "~0.10", "justinrainbow/json-schema" : "~1.3", "mediavorus/mediavorus" : "~0.4.0", - "media-alchemyst/media-alchemyst" : "dev-master", + "media-alchemyst/media-alchemyst" : "~0.4", "monolog/monolog" : "~1.3", "mrclay/minify" : "~2.1.6", "neutron/silex-imagine-provider" : "~0.1.0", diff --git a/composer.lock b/composer.lock index 50576ec33f..8f23472296 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "fadb1c02db78a5cbeec681a90b45fdf8", + "hash": "51c29e26e9366f0675b21bc0f69ecac5", "packages": [ { "name": "alchemy-fr/tcpdf-clone", @@ -1524,16 +1524,16 @@ }, { "name": "media-alchemyst/media-alchemyst", - "version": "dev-master", + "version": "0.4.7", "source": { "type": "git", "url": "https://github.com/alchemy-fr/Media-Alchemyst.git", - "reference": "62fec183416ce6dfdf22e832f0de3c7442a23598" + "reference": "0d7b04a5367929efd95edd68ab361dffa70bb8b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/alchemy-fr/Media-Alchemyst/zipball/62fec183416ce6dfdf22e832f0de3c7442a23598", - "reference": "62fec183416ce6dfdf22e832f0de3c7442a23598", + "url": "https://api.github.com/repos/alchemy-fr/Media-Alchemyst/zipball/0d7b04a5367929efd95edd68ab361dffa70bb8b5", + "reference": "0d7b04a5367929efd95edd68ab361dffa70bb8b5", "shasum": "" }, "require": { @@ -1593,7 +1593,7 @@ "video", "video processing" ], - "time": "2014-10-20 07:22:23" + "time": "2015-01-14 15:28:58" }, { "name": "mediavorus/mediavorus", @@ -3290,12 +3290,12 @@ "version": "v1.5.0", "source": { "type": "git", - "url": "https://github.com/Behat/Mink.git", + "url": "https://github.com/minkphp/Mink.git", "reference": "0769e6d9726c140a54dbf827a438c0f9912749fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Mink/zipball/0769e6d9726c140a54dbf827a438c0f9912749fe", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/0769e6d9726c140a54dbf827a438c0f9912749fe", "reference": "0769e6d9726c140a54dbf827a438c0f9912749fe", "shasum": "" }, @@ -3345,12 +3345,12 @@ "version": "v1.1.0", "source": { "type": "git", - "url": "https://github.com/Behat/MinkBrowserKitDriver.git", + "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", "reference": "63960c8fcad4529faad1ff33e950217980baa64c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkBrowserKitDriver/zipball/63960c8fcad4529faad1ff33e950217980baa64c", + "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/63960c8fcad4529faad1ff33e950217980baa64c", "reference": "63960c8fcad4529faad1ff33e950217980baa64c", "shasum": "" }, @@ -3451,12 +3451,12 @@ "version": "v1.0.9", "source": { "type": "git", - "url": "https://github.com/Behat/MinkGoutteDriver.git", + "url": "https://github.com/minkphp/MinkGoutteDriver.git", "reference": "fa1b073b48761464feb0b05e6825da44b20118d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkGoutteDriver/zipball/fa1b073b48761464feb0b05e6825da44b20118d8", + "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/fa1b073b48761464feb0b05e6825da44b20118d8", "reference": "fa1b073b48761464feb0b05e6825da44b20118d8", "shasum": "" }, @@ -3502,12 +3502,12 @@ "version": "v1.1.1", "source": { "type": "git", - "url": "https://github.com/Behat/MinkSelenium2Driver.git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", "reference": "bcf1b537de37db6db0822d9e7bd97e600fd7a476" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkSelenium2Driver/zipball/bcf1b537de37db6db0822d9e7bd97e600fd7a476", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/bcf1b537de37db6db0822d9e7bd97e600fd7a476", "reference": "bcf1b537de37db6db0822d9e7bd97e600fd7a476", "shasum": "" }, @@ -3614,12 +3614,12 @@ "version": "v1.0.6", "source": { "type": "git", - "url": "https://github.com/fabpot/Goutte.git", + "url": "https://github.com/FriendsOfPHP/Goutte.git", "reference": "06a5451288ffddd204b10fa6c6f9ab2b86dd515d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Goutte/zipball/06a5451288ffddd204b10fa6c6f9ab2b86dd515d", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/06a5451288ffddd204b10fa6c6f9ab2b86dd515d", "reference": "06a5451288ffddd204b10fa6c6f9ab2b86dd515d", "shasum": "" }, @@ -3655,9 +3655,7 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "email": "fabien@symfony.com" } ], "description": "A simple PHP Web Scraper", @@ -4109,11 +4107,11 @@ "minimum-stability": "stable", "stability-flags": { "imagine/imagine": 20, - "media-alchemyst/media-alchemyst": 20, "phpexiftool/phpexiftool": 20, "doctrine/data-fixtures": 20 }, "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": ">=5.3.3" }, From 10c3869ca3fd9729fd549bb17aade984dfda4439 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Thu, 15 Jan 2015 13:22:37 +0100 Subject: [PATCH 28/46] PHRAS-374 Add command to rebuild subdefs --- bin/console | 2 + .../Phrasea/Command/BuildMissingSubdefs.php | 39 +--- lib/Alchemy/Phrasea/Command/BuildSubdefs.php | 171 ++++++++++++++++++ lib/Alchemy/Phrasea/Controller/Prod/Tools.php | 6 +- lib/classes/record/adapter.php | 34 +++- .../web/prod/actions/Tools/index.html.twig | 17 +- 6 files changed, 222 insertions(+), 47 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Command/BuildSubdefs.php diff --git a/bin/console b/bin/console index 4fb292526e..03ba3846ad 100755 --- a/bin/console +++ b/bin/console @@ -16,6 +16,7 @@ namespace KonsoleKommander; * @license http://opensource.org/licenses/gpl-3.0 GPLv3 * @link www.phraseanet.com */ +use Alchemy\Phrasea\Command\BuildSubdefs; use Alchemy\Phrasea\Command\Plugin\ListPlugin; use Alchemy\Phrasea\Command\Setup\H264ConfigurationDumper; use Alchemy\Phrasea\Command\Setup\H264MappingGenerator; @@ -97,6 +98,7 @@ $cli->command(new CreateCollection('collection:create')); $cli->command(new RecordAdd('records:add')); $cli->command(new RescanTechnicalDatas('records:rescan-technical-datas')); $cli->command(new BuildMissingSubdefs('records:build-missing-subdefs')); +$cli->command(new BuildSubdefs('records:build-subdefs')); $cli->command(new AddPlugin()); $cli->command(new ListPlugin()); diff --git a/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php index 048fd68452..208d698c6b 100644 --- a/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php +++ b/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php @@ -44,9 +44,6 @@ class BuildMissingSubdefs extends Command $n = 0; foreach ($this->container['phraseanet.appbox']->get_databoxes() as $databox) { - - $subdefStructure = $databox->get_subdef_structure(); - $sql = 'SELECT record_id FROM record WHERE parent_record_id = 0'; $stmt = $databox->get_connection()->prepare($sql); $stmt->execute(); @@ -56,38 +53,14 @@ class BuildMissingSubdefs extends Command foreach ($rs as $row) { $record = $databox->get_record($row['record_id']); - try { - $record->get_hd_file(); - } catch (FileNotFoundException $e) { - continue; - } + $wanted_subdefs = $record->get_missing_subdefs(); - $group = $subdefStructure->getSubdefGroup($record->get_type()); + if (count($wanted_subdefs) > 0) { + $record->generate_subdefs($databox, $this->container, $wanted_subdefs); - if ($group) { - foreach ($group as $subdef) { - - $todo = false; - - if ( ! $record->has_subdef($subdef->get_name())) { - $todo = true; - } - if (in_array($subdef->get_name(), array('preview', 'thumbnail', 'thumbnailgif'))) { - try { - $sub = $record->get_subdef($subdef->get_name()); - if ( ! $sub->is_physically_present()) { - $todo = true; - } - } catch (\Exception_Media_SubdefNotFound $e) { - $todo = true; - } - } - - if ($todo) { - $record->generate_subdefs($databox, $this->container, array($subdef->get_name())); - $this->container['monolog']->addInfo("generate " . $subdef->get_name() . " for record " . $record->get_record_id()); - $n ++; - } + foreach ($wanted_subdefs as $subdef) { + $this->container['monolog']->addInfo("generate " .$subdef . " for record " . $record->get_record_id()); + $n ++; } } diff --git a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php new file mode 100644 index 0000000000..bcf1abdb82 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php @@ -0,0 +1,171 @@ +setDescription('Build subviews for given subview names and record types'); + $this->addArgument('databox', InputArgument::REQUIRED, 'The databox id'); + $this->addArgument('type', InputArgument::REQUIRED, 'Types of the document to rebuild'); + $this->addArgument('subdefs', InputArgument::REQUIRED, 'Names of sub-definition to re-build'); + $this->addOption('max_record', 'max', InputOption::VALUE_OPTIONAL, 'Max record id'); + $this->addOption('min_record', 'min', InputOption::VALUE_OPTIONAL, 'Min record id'); + + return $this; + } + + /** + * {@inheritdoc} + */ + protected function doExecute(InputInterface $input, OutputInterface $output) + { + $availableTypes = array('document', 'audio', 'video', 'image', 'flash', 'map'); + + $typesOption = $input->getArgument('type'); + + $recordsType = explode(',', $typesOption); + $recordsType = array_filter($recordsType, function($type) use($availableTypes) { + return in_array($type, $availableTypes); + }); + + if (count($recordsType) === 0) { + $output->write(sprintf('Invalid records type provided %s', implode(', ', $availableTypes))); + return; + } + + $subdefsOption = $input->getArgument('subdefs'); + $subdefsName = explode(',', $subdefsOption); + + if (count($subdefsOption) === 0) { + $output->write('No subdef options provided'); + return; + } + + $sqlCount = " + SELECT COUNT(DISTINCT(r.record_id)) AS nb_records + FROM record r + INNER JOIN subdef s + ON (r.record_id = s.record_id) + WHERE s.name IN (?) + AND r.type IN (?) + "; + + $types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY); + $params = array($subdefsName, $recordsType); + + if (null !== $min = $input->getOption('min_record')) { + $sqlCount .= " AND (r.record_id >= ?)"; + + $params[] = (int) $min; + $types[] = \PDO::PARAM_INT; + } + if (null !== $max = $input->getOption('max_record')) { + $sqlCount .= " AND (r.record_id <= ?)"; + + $params[] = (int) $max; + $types[] = \PDO::PARAM_INT; + } + + list($sqlCount, $stmtParams) = SQLParserUtils::expandListParameters($sqlCount, $params, $types); + + $totalRecords = 0; + foreach ($this->container['phraseanet.appbox']->get_databoxes() as $databox) { + $connection = $databox->get_connection(); + $stmt = $connection->prepare($sqlCount); + $stmt->execute($stmtParams); + $row = $stmt->fetch(); + $totalRecords += $row['nb_records']; + } + + if ($totalRecords === 0) { + return; + } + + $progress = $this->getHelperSet()->get('progress'); + + $progress->start($output, $totalRecords); + + $progress->display(); + + $databox = $this->container['phraseanet.appbox']->get_databox($input->getArgument('databox')); + + $sql = " + SELECT DISTINCT(r.record_id) + FROM record r + INNER JOIN subdef s + ON (r.record_id = s.record_id) + WHERE s.name IN (?) + AND r.type IN (?) + "; + + $types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY); + $params = array($subdefsName, $recordsType); + + if ($min) { + $sql .= " AND (r.record_id >= ?)"; + + $params[] = (int) $min; + $types[] = \PDO::PARAM_INT; + } + if ($max) { + $sql .= " AND (r.record_id <= ?)"; + + $params[] = (int) $max; + $types[] = \PDO::PARAM_INT; + } + + list($sql, $stmtParams) = SQLParserUtils::expandListParameters($sql, $params, $types); + + $connection = $databox->get_connection(); + $stmt = $connection->prepare($sql); + $stmt->execute($stmtParams); + $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC); + + foreach ($rows as $row) { + $output->write(sprintf(' (#%s)', $row['record_id'])); + + $record = new \record_adapter($this->container, $databox->get_sbas_id(), $row['record_id']); + + $subdefs = array_filter($record->get_subdefs(), function($subdef) use ($subdefsName) { + return in_array($subdef->get_name(), $subdefsName); + }); + + foreach ($subdefs as $subdef) { + $subdef->remove_file(); + } + + $record->generate_subdefs($databox, $this->container, $subdefsName); + + $stmt->closeCursor(); + + $progress->advance(); + } + + unset($rows, $record, $stmt, $connection); + + $progress->finish(); + } +} diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php b/lib/Alchemy/Phrasea/Controller/Prod/Tools.php index 53bc7cd94e..35ecfa416a 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Tools.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Tools.php @@ -90,10 +90,11 @@ class Tools implements ControllerProviderInterface $controllers->post('/image/', function (Application $app, Request $request) { $return = array('success' => true); + $force = $request->request->get('force_substitution') == '1'; + $selection = RecordsRequest::fromRequest($app, $request, false, array('canmodifrecord')); foreach ($selection as $record) { - $substituted = false; foreach ($record->get_subdefs() as $subdef) { if ($subdef->is_substituted()) { @@ -102,11 +103,12 @@ class Tools implements ControllerProviderInterface } } - if (!$substituted || $request->request->get('ForceThumbSubstit') == '1') { + if (!$substituted || $force) { $record->rebuild_subdefs(); } } + return $app->json($return); })->bind('prod_tools_image'); diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php index d2a0b6a81c..182a71968a 100644 --- a/lib/classes/record/adapter.php +++ b/lib/classes/record/adapter.php @@ -1202,7 +1202,7 @@ class record_adapter implements record_Interface, cache_cacheableInterface * * @return record_adapter */ - public function rebuild_subdefs() + public function rebuild_subdefs() { $connbas = connection::getPDOConnection($this->app, $this->get_sbas_id()); $sql = 'UPDATE record SET jeton=(jeton | ' . JETON_MAKE_SUBDEF . ') WHERE record_id = :record_id'; @@ -1213,6 +1213,38 @@ class record_adapter implements record_Interface, cache_cacheableInterface return $this; } + public function get_missing_subdefs() + { + $databox = $this->get_databox(); + + try { + $this->get_hd_file(); + } catch (\Exception $e) { + return array(); + } + + $subDefDefinitions = $databox->get_subdef_structure()->getSubdefGroup($this->get_type()); + if (!$subDefDefinitions) { + return array(); + } + + $record = $this; + $wanted_subdefs = array_map(function($subDef) { + return $subDef->get_name(); + }, array_filter($subDefDefinitions, function($subDef) use ($record) { + return !$record->has_subdef($subDef->get_name()); + })); + + + $missing_subdefs = array_map(function($subDef) { + return $subDef->get_name(); + }, array_filter($this->get_subdefs(), function($subdef) { + return !$subdef->is_physically_present(); + })); + + return array_values(array_merge($wanted_subdefs, $missing_subdefs)); + } + /** * * @return record_adapter diff --git a/templates/web/prod/actions/Tools/index.html.twig b/templates/web/prod/actions/Tools/index.html.twig index b4a0fbbba5..63aecdf671 100644 --- a/templates/web/prod/actions/Tools/index.html.twig +++ b/templates/web/prod/actions/Tools/index.html.twig @@ -70,25 +70,20 @@  {% trans "Reconstruire les sous definitions" %}  {% if nbThumbSubstitute > 0 %}
- {% trans "Attention, certain documents ont des sous-definitions substituees"%} + {% trans "Attention, certain documents ont des sous-definitions substituees" %}

{% else %} - + {% endif %}
- +

+ {{ 'Are you sure you want to rebuild the sub-definitions of selected records?' }} +

From 3daa96a1411ae0bf53f7bee9766d799f6adb25ac Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 20 Jan 2015 18:30:11 +0100 Subject: [PATCH 29/46] PHRAS-357 Fix delete user oauth apps & accounts --- lib/classes/User/Adapter.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/classes/User/Adapter.php b/lib/classes/User/Adapter.php index 39f4517272..87cbd98502 100644 --- a/lib/classes/User/Adapter.php +++ b/lib/classes/User/Adapter.php @@ -967,7 +967,6 @@ class User_Adapter implements User_Interface, cache_cacheableInterface } /** - * @todo close all open session * @return type */ public function delete() @@ -1038,6 +1037,24 @@ class User_Adapter implements User_Interface, cache_cacheableInterface $stmt->execute(array(':usr_id' => $this->get_id())); $stmt->closeCursor(); + // delete created app + $oauthApps = API_OAuth2_Application::load_dev_app_by_user($this->app, $this); + + // delete accounts for thos app + foreach ($oauthApps as $oauthApp) { + $account = API_OAuth2_Account::load_with_user($this->app, $oauthApp, $this); + $account->delete(); + $oauthApp->delete(); + } + + // delete any other account + $oauthApps = API_OAuth2_Application::load_app_by_user($this->app, $this); + + foreach ($oauthApps as $oauthApp) { + $account = API_OAuth2_Account::load_with_user($this->app, $oauthApp, $this); + $account->delete(); + } + unset(self::$_instance[$this->get_id()]); return; From 344cc0cdd8540f260768e402c60abc901f275585 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Tue, 27 Jan 2015 16:55:07 +0100 Subject: [PATCH 30/46] fix #PHRAS-388 #time 4h --- lib/classes/API/V1/adapter.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/classes/API/V1/adapter.php b/lib/classes/API/V1/adapter.php index d4a28a3f2c..45c70414b8 100644 --- a/lib/classes/API/V1/adapter.php +++ b/lib/classes/API/V1/adapter.php @@ -1460,25 +1460,25 @@ class API_V1_adapter extends API_V1_Abstract return null; } - if ($this->app['authentication']->isAuthenticated()) { - if ($media->get_name() !== 'document' && false === $this->app['authentication']->getUser()->ACL()->has_access_to_subdef($record, $media->get_name())) { + if ($media->get_name() !== 'document' && false === $this->app['authentication']->getUser()->ACL()->has_access_to_subdef($record, $media->get_name())) { return null; } else if ($media->get_name() === 'document' - && !$this->app['authentication']->getUser()->ACL()->has_right_on_base($record->get_base_id(), 'candwnldhd') + && !$this->app['authentication']->getUser()->ACL()->has_right_on_base($record->get_base_id(), 'candwnldhd') && !$this->app['authentication']->getUser()->ACL()->has_hd_grant($record)) { return null; } } - - $databox = $record->get_databox(); - try { - $subDefDefinition = $databox->get_subdef_structure()->get_subdef($record->get_type(), $media->get_name()); - } catch (Exception_Databox_SubdefNotFound $e) { - return null; + if($media->get_name() != 'document') { + $databox = $record->get_databox(); + try { + $subDefDefinition = $databox->get_subdef_structure()->get_subdef($record->get_type(), $media->get_name()); + } catch (Exception_Databox_SubdefNotFound $e) { + return null; + } } - if (false === $subDefDefinition->is_downloadable()) { + if ($media->get_name() != 'document' && false === $subDefDefinition->is_downloadable()) { return null; } From 82a5082335c3e1484ce829c690c77295ae4e7e6c Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Tue, 27 Jan 2015 18:11:08 +0100 Subject: [PATCH 31/46] fix #PHRAS-316 #time 1h --- composer.json | 2 +- composer.lock | 94 +++++++++++++++++++++------------------------------ 2 files changed, 39 insertions(+), 57 deletions(-) diff --git a/composer.json b/composer.json index 7f896af3f3..ba3e73bbdb 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "alchemy/geonames-api-consumer" : "~0.1.0", "goodby/csv" : "~1.0", "guzzle/guzzle" : "~3.0", - "imagine/imagine" : "dev-0.6.1-flatten-layer as 0.6.1", + "imagine/imagine" : "dev-alchemy-0.6.2 as 0.6.2", "jms/serializer" : "~0.10", "justinrainbow/json-schema" : "~1.3", "mediavorus/mediavorus" : "~0.4.0", diff --git a/composer.lock b/composer.lock index 8f23472296..e0f9791960 100644 --- a/composer.lock +++ b/composer.lock @@ -4,22 +4,16 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "51c29e26e9366f0675b21bc0f69ecac5", + "hash": "10842ebc1702e5e2e097fe883063b20d", "packages": [ { "name": "alchemy-fr/tcpdf-clone", "version": "6.0.039", "source": { "type": "git", - "url": "https://github.com/alchemy-fr/tcpdf-clone.git", + "url": "https://github.com/alchemy-fr/tcpdf-clone", "reference": "2ba0248a7187f1626df6c128750650416267f0e7" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/alchemy-fr/tcpdf-clone/zipball/2ba0248a7187f1626df6c128750650416267f0e7", - "reference": "2ba0248a7187f1626df6c128750650416267f0e7", - "shasum": "" - }, "require": { "php": ">=5.3.0" }, @@ -66,10 +60,6 @@ "qrcode", "tcpdf" ], - "support": { - "source": "https://github.com/alchemy-fr/tcpdf-clone/tree/6.0.039", - "issues": "https://github.com/alchemy-fr/tcpdf-clone/issues" - }, "time": "2013-10-13 16:11:17" }, { @@ -113,7 +103,7 @@ "homepage": "http://www.lickmychip.com/" }, { - "name": "nlegoff", + "name": "Nicolas Le Goff", "email": "legoff.n@gmail.com" }, { @@ -769,8 +759,7 @@ { "name": "Jonathan Wage", "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/", - "role": "Creator" + "homepage": "http://www.jwage.com/" }, { "name": "Guilherme Blanco", @@ -788,7 +777,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", + "homepage": "http://jmsyst.com", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -842,7 +831,7 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", + "homepage": "http://jmsyst.com", "role": "Developer of wrapped JMSSerializerBundle" } ], @@ -930,13 +919,13 @@ "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/igorw/evenement.git", - "reference": "fa966683e7df3e5dd5929d984a44abfbd6bafe8d" + "url": "https://github.com/igorw/evenement", + "reference": "v1.0.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/fa966683e7df3e5dd5929d984a44abfbd6bafe8d", - "reference": "fa966683e7df3e5dd5929d984a44abfbd6bafe8d", + "url": "https://github.com/igorw/evenement/zipball/v1.0.0", + "reference": "v1.0.0", "shasum": "" }, "require": { @@ -963,7 +952,7 @@ "keywords": [ "event-dispatcher" ], - "time": "2012-05-30 15:01:08" + "time": "2012-05-30 08:01:08" }, { "name": "facebook/php-sdk", @@ -1242,16 +1231,16 @@ }, { "name": "imagine/imagine", - "version": "dev-0.6.1-flatten-layer", + "version": "dev-alchemy-0.6.2", "source": { "type": "git", "url": "https://github.com/alchemy-fr/Imagine.git", - "reference": "372f36e2d76e4ca1fbdccda57c23b8483ed700b1" + "reference": "6605d13e3b24f335fe80099c193546671158c041" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/alchemy-fr/Imagine/zipball/372f36e2d76e4ca1fbdccda57c23b8483ed700b1", - "reference": "372f36e2d76e4ca1fbdccda57c23b8483ed700b1", + "url": "https://api.github.com/repos/alchemy-fr/Imagine/zipball/6605d13e3b24f335fe80099c193546671158c041", + "reference": "6605d13e3b24f335fe80099c193546671158c041", "shasum": "" }, "require": { @@ -1268,7 +1257,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-develop": "0.6-dev" + "dev-develop": "0.7-dev" } }, "autoload": { @@ -1295,9 +1284,9 @@ "image processing" ], "support": { - "source": "https://github.com/alchemy-fr/Imagine/tree/0.6.1-flatten-layer" + "source": "https://github.com/alchemy-fr/Imagine/tree/alchemy-0.6.2" }, - "time": "2014-11-19 14:31:17" + "time": "2015-01-13 18:12:26" }, { "name": "jms/metadata", @@ -1749,7 +1738,7 @@ ], "authors": [ { - "name": "Steve Clay", + "name": "Stephen Clay", "email": "steve@mrclay.org", "homepage": "http://www.mrclay.org/", "role": "Developer" @@ -1853,21 +1842,21 @@ "source": { "type": "git", "url": "https://github.com/romainneutron/Imagine-Silex-Service-Provider.git", - "reference": "a8a7862ae90419f2b23746cd8436c2310e4eb084" + "reference": "0.1.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/romainneutron/Imagine-Silex-Service-Provider/zipball/a8a7862ae90419f2b23746cd8436c2310e4eb084", - "reference": "a8a7862ae90419f2b23746cd8436c2310e4eb084", + "url": "https://api.github.com/repos/romainneutron/Imagine-Silex-Service-Provider/zipball/0.1.2", + "reference": "0.1.2", "shasum": "" }, "require": { "imagine/imagine": "*", "php": ">=5.3.3", - "silex/silex": "~1.0" + "silex/silex": ">=1.0,<2.0" }, "require-dev": { - "symfony/browser-kit": "~2.0" + "symfony/browser-kit": ">=2.0,<3.0" }, "type": "library", "autoload": { @@ -2342,7 +2331,7 @@ "metadata" ], "support": { - "source": "https://github.com/alchemy-fr/PHPExiftool/tree/dev" + "source": "https://github.com/alchemy-fr/PHPExiftool/tree/0.4.1-mwg-metadata-copy" }, "time": "2014-10-08 16:09:02" }, @@ -2400,12 +2389,12 @@ "version": "v1.1.1", "source": { "type": "git", - "url": "https://github.com/fabpot/Pimple.git", + "url": "https://github.com/silexphp/Pimple.git", "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d", "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d", "shasum": "" }, @@ -2430,9 +2419,7 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "email": "fabien@symfony.com" } ], "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", @@ -2654,7 +2641,7 @@ }, { "name": "Phraseanet Team", - "email": "info@alchemy.fr", + "email": "support@alchemy.fr", "homepage": "http://www.phraseanet.com/" } ], @@ -2701,9 +2688,7 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "email": "fabien@symfony.com" }, { "name": "Chris Corbyn" @@ -2921,12 +2906,12 @@ "version": "v1.1.0", "source": { "type": "git", - "url": "https://github.com/fabpot/Twig-extensions.git", + "url": "https://github.com/twigphp/Twig-extensions.git", "reference": "c0ab818595338dd5569369bfce2552d02cec5d50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Twig-extensions/zipball/c0ab818595338dd5569369bfce2552d02cec5d50", + "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/c0ab818595338dd5569369bfce2552d02cec5d50", "reference": "c0ab818595338dd5569369bfce2552d02cec5d50", "shasum": "" }, @@ -2951,9 +2936,7 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" + "email": "fabien@symfony.com" } ], "description": "Common additional features for Twig that do not directly belong in core", @@ -2969,12 +2952,12 @@ "version": "v1.16.0", "source": { "type": "git", - "url": "https://github.com/fabpot/Twig.git", + "url": "https://github.com/twigphp/Twig.git", "reference": "8ce37115802e257a984a82d38254884085060024" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Twig/zipball/8ce37115802e257a984a82d38254884085060024", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8ce37115802e257a984a82d38254884085060024", "reference": "8ce37115802e257a984a82d38254884085060024", "shasum": "" }, @@ -4092,9 +4075,9 @@ ], "aliases": [ { - "alias": "0.6.1", - "alias_normalized": "0.6.1.0", - "version": "dev-0.6.1-flatten-layer", + "alias": "0.6.2", + "alias_normalized": "0.6.2.0", + "version": "dev-alchemy-0.6.2", "package": "imagine/imagine" }, { @@ -4111,7 +4094,6 @@ "doctrine/data-fixtures": 20 }, "prefer-stable": false, - "prefer-lowest": false, "platform": { "php": ">=5.3.3" }, From d2063cc1955d9c10ca040bce89d48b83b0cdb69b Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Tue, 27 Jan 2015 19:25:12 +0100 Subject: [PATCH 32/46] fix #PHRAS-359 #time 30m --- www/skins/admin/template-dialogs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/skins/admin/template-dialogs.js b/www/skins/admin/template-dialogs.js index 950854757e..87c9f6393a 100644 --- a/www/skins/admin/template-dialogs.js +++ b/www/skins/admin/template-dialogs.js @@ -4,7 +4,7 @@ var dialogUserResetTemplateConfirm = function (callback) { buttons[language.reset_template_do_reset_apply_button] = function () { p4.Dialog.Close(2); callback('1'); }; var $dialog = p4.Dialog.Create({ - size : '500x150', + size : '500x200', closeOnEscape : true, closeButton:false, cancelButton:true, @@ -21,7 +21,7 @@ var dialogUserTemplate = function (callback) { buttons[language.reset_template_do_reset_button] = function () { p4.Dialog.Close(1); dialogUserResetTemplateConfirm(callback); }; var $dialog = p4.Dialog.Create({ - size : '500x150', + size : '500x200', closeOnEscape : true, closeButton:false, cancelButton:true, From 36e68063626ab16364b110d419ff7568356c0942 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 28 Jan 2015 10:41:46 +0100 Subject: [PATCH 33/46] #PHRAS-359 #time 5m wide is better --- www/skins/admin/template-dialogs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/skins/admin/template-dialogs.js b/www/skins/admin/template-dialogs.js index 87c9f6393a..1195650eab 100644 --- a/www/skins/admin/template-dialogs.js +++ b/www/skins/admin/template-dialogs.js @@ -4,7 +4,7 @@ var dialogUserResetTemplateConfirm = function (callback) { buttons[language.reset_template_do_reset_apply_button] = function () { p4.Dialog.Close(2); callback('1'); }; var $dialog = p4.Dialog.Create({ - size : '500x200', + size : '550x200', closeOnEscape : true, closeButton:false, cancelButton:true, @@ -21,7 +21,7 @@ var dialogUserTemplate = function (callback) { buttons[language.reset_template_do_reset_button] = function () { p4.Dialog.Close(1); dialogUserResetTemplateConfirm(callback); }; var $dialog = p4.Dialog.Create({ - size : '500x200', + size : '550x200', closeOnEscape : true, closeButton:false, cancelButton:true, From 2cf1a45a5bd73a2219444cfbfc05c77cf784da03 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Tue, 27 Jan 2015 18:33:32 +0100 Subject: [PATCH 34/46] fix #PHRAS-343 #time 20m --- www/skins/prod/jquery.main-prod.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/skins/prod/jquery.main-prod.js b/www/skins/prod/jquery.main-prod.js index 25a2689b88..b9bf5937fa 100644 --- a/www/skins/prod/jquery.main-prod.js +++ b/www/skins/prod/jquery.main-prod.js @@ -760,9 +760,9 @@ $(document).ready(function () { var $this = $(this); var $record_types = $('#recordtype_sel'); if ($this.hasClass('mode_type_reg')) { - $record_types.attr('disabled', true); + $record_types.hide(); } else { - $record_types.removeAttr('disabled'); + $record_types.show(); } }); From 39c53421ad4d81b6e56d057a3eca659a09ec910b Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 28 Jan 2015 14:05:01 +0100 Subject: [PATCH 35/46] #PHRAS-271 #time 1h --- .../Phrasea/SearchEngine/SearchEngineOptions.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php index 72a5b6563c..acb05fd15d 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php +++ b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineOptions.php @@ -653,11 +653,14 @@ class SearchEngineOptions } $bas = array_filter($bas, function ($collection) use ($app) { - if ($app['authentication']->isAuthenticated()) { - return $app['authentication']->getUser()->ACL()->has_access_to_base($collection->get_base_id()); - } else { - return in_array($collection, $app->getOpenCollections()); + if($collection !== null) { + if ($app['authentication']->isAuthenticated()) { + return $app['authentication']->getUser()->ACL()->has_access_to_base($collection->get_base_id()); + } else { + return in_array($collection, $app->getOpenCollections()); + } } + return false; // CollectionNotFound }); $databoxes = array(); From f38f87a7d2ee7e425f726cd2646f501859db1b57 Mon Sep 17 00:00:00 2001 From: Jean-Yves Gaulier Date: Wed, 28 Jan 2015 14:24:37 +0100 Subject: [PATCH 36/46] #PHRAS-260 #time 5m --- .../web/admin/collection/collection.html.twig | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/templates/web/admin/collection/collection.html.twig b/templates/web/admin/collection/collection.html.twig index 020ae778b8..461f8d7547 100644 --- a/templates/web/admin/collection/collection.html.twig +++ b/templates/web/admin/collection/collection.html.twig @@ -213,22 +213,6 @@ {% endif %} -{# Bandeau de présentation #} -
-
{% trans 'admin::base:collection: image de presentation : ' %}
- {% if collection.getPresentation(bas_id) is not empty %} -
{{ collection.getPresentation(bas_id)| raw }}
- {% if app['authentication'].getUser().ACL.has_right_on_base(bas_id, 'manage') %} -
- -
- {% endif%} - {% endif %} -
- {# Invalid file type modal shown when uploaded logo file is invalid #}