Merge branch 'master' into PHRAS-3144-install-plugin

This commit is contained in:
Nicolas Maillat
2020-06-24 17:52:05 +02:00
committed by GitHub
12 changed files with 73 additions and 27 deletions

View File

@@ -193,17 +193,20 @@ XDEBUG_REMOTE_HOST=host.docker.internal
Plugins can be installed during build if you set the `PHRASEANET_PLUGINS` env var as follows:
```bash
PHRASEANET_PLUGINS="git@github.com:alchemy-fr/Phraseanet-plugin-webgallery.git"
PHRASEANET_PLUGINS="https://github.com/alchemy-fr/Phraseanet-plugin-expose.git"
# You can optionally precise the branch to install
# If not precised, the main branch will be pulled
PHRASEANET_PLUGINS="git@github.com:alchemy-fr/Phraseanet-plugin-webgallery.git(custom-branch)"
# Plugins are separated by spaces
PHRASEANET_PLUGINS="git@github.com:foo/bar.git(branch-1) git@github.com:baz/42.git"
# Plugins are separated by semicolons
PHRASEANET_PLUGINS="git@github.com:foo/bar.git(branch-1);git@github.com:baz/42.git"
```
> Prefer the HTTPS URL for public repositories, you will not be required to provide your SSH key.
If you install private plugins, make sure you export your SSH private key content in order to allow docker build to access the GIT repository:
Also ensure you're using the SSH URL form (i.e: `git@github.com:alchemy-fr/repo.git`).
```bash
export PHRASEANET_SSH_PRIVATE_KEY=$(cat ~/.ssh/id_rsa)
# or if your private key is protected by a passphrase:

View File

@@ -29,7 +29,7 @@ class InstallCommand extends Command
mkdir($pluginsDir);
}
foreach (explode(' ', $plugins) as $key => $plugin) {
foreach (explode(';', $plugins) as $key => $plugin) {
$plugin = trim($plugin);
$repo = $plugin;
$branch = 'master';

View File

@@ -2093,7 +2093,7 @@ class V1Controller extends Controller
try {
$collection = \collection::getByBaseId($this->app, $request->get('base_id'));
$record->move_to_collection($collection, $this->getApplicationBox());
$record->move_to_collection($collection);
return Result::create($request, ["record" => $this->listRecord($request, $record)])->createResponse();
} catch (\Exception $e) {

View File

@@ -17,7 +17,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class V3MetadatasController extends Controller
class V3RecordController extends Controller
{
use JsonBodyAware;
use DispatcherAware;
@@ -32,7 +32,7 @@ class V3MetadatasController extends Controller
*
* @return Response
*/
public function setmetadatasAction(Request $request, $databox_id, $record_id)
public function indexAction_patch(Request $request, $databox_id, $record_id)
{
$struct = $this->findDataboxById($databox_id)->get_meta_structure();
$record = $this->findDataboxById($databox_id)->get_record($record_id);
@@ -59,7 +59,10 @@ class V3MetadatasController extends Controller
}
// do sb ops
if (is_array($b->status)) {
$debug['sb_ops'] = $this->do_status($struct, $record, $b->status);
$debug['sb_ops'] = $this->do_status($record, $b->status);
}
if(!is_null($b->base_id)) {
$debug['coll_ops'] = $this->do_collection($record, $b->base_id);
}
}
catch (Exception $e) {
@@ -77,13 +80,21 @@ class V3MetadatasController extends Controller
return Result::create($request, $ret)->createResponse();
}
/**
* @param record_adapter $record
* @param $base_id
*/
private function do_collection(record_adapter $record, $base_id)
{
$record->move_to_collection($this->getApplicationBox()->get_collection($base_id));
}
//////////////////////////////////
/// TODO : keep multi-values uniques !
/// it should be done in record_adapter
//////////////////////////////////
/**
* @param databox_field[] $struct
* @param record_adapter $record
@@ -94,12 +105,10 @@ class V3MetadatasController extends Controller
private function do_metadatas($struct, record_adapter $record, $metadatas)
{
$structByKey = [];
$nameToStrucId = [];
$allStructFields = [];
foreach ($struct as $f) {
$nameToStrucId[$f->get_name()] = $f->get_id();
$allStructFields[$f->get_id()] = $f;
$structByKey[$f->get_id()] = &$allStructFields[$f->get_id()];;
$structByKey[$f->get_id()] = &$allStructFields[$f->get_id()];
$structByKey[$f->get_name()] = &$allStructFields[$f->get_id()];
}
@@ -123,6 +132,9 @@ class V3MetadatasController extends Controller
$fields_list[] = $structByKey[$k]->get_name();
$struct_fields[$structByKey[$k]->get_id()] = $structByKey[$k];
}
else {
throw new Exception(sprintf("unknown field (%s).", $k));
}
}
}
else {
@@ -187,13 +199,12 @@ class V3MetadatasController extends Controller
}
/**
* @param $struct
* @param $record
* @param $statuses
* @return array
* @throws Exception
*/
private function do_status($struct, $record, $statuses)
private function do_status(record_adapter $record, $statuses)
{
$datas = strrev($record->getStatus());

View File

@@ -115,13 +115,13 @@ class MoveCollectionController extends Controller
foreach ($records as $record) {
$oldCollectionId = $record->getCollection()->get_coll_id();
$record->move_to_collection($collection, $this->getApplicationBox());
$record->move_to_collection($collection);
if ($request->request->get("chg_coll_son") == "1") {
/** @var \record_adapter $child */
foreach ($record->getChildren() as $child) {
if ($this->getAclForUser()->has_right_on_base($child->getBaseId(), \ACL::CANDELETERECORD)) {
$child->move_to_collection($collection, $this->getApplicationBox());
$child->move_to_collection($collection);
}
}
}

View File

@@ -242,7 +242,7 @@ class RecordController extends Controller
$this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record));
} else {
// move to trash collection
$record->move_to_collection($trashCollectionsBySbasId[$sbasId], $this->getApplicationBox());
$record->move_to_collection($trashCollectionsBySbasId[$sbasId]);
// disable permalinks
foreach($record->get_subdefs() as $subdef) {
if( ($pl = $subdef->get_permalink()) ) {

View File

@@ -13,6 +13,9 @@ use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Core\Event\Thesaurus as ThesaurusEvent;
use Alchemy\Phrasea\Core\Event\Thesaurus\ThesaurusEvents;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
use Alchemy\Phrasea\WorkerManager\Event\PopulateIndexEvent;
use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents;
use Doctrine\DBAL\Driver\Connection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -1222,6 +1225,26 @@ class ThesaurusController extends Controller
]);
}
/**
* Order to populate databox
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function populate(Request $request)
{
$options = $this->getElasticsearchOptions();
$data['host'] = $options->getHost();
$data['port'] = $options->getPort();
$data['indexName'] = $options->getIndexName();
$data['databoxIds'] = [$request->get('databox_id')];
$this->getDispatcher()->dispatch(WorkerEvents::POPULATE_INDEX, new PopulateIndexEvent($data));
return $this->app->json($data);
}
/**
* @param Request $request
* @return Response
@@ -3031,4 +3054,12 @@ class ThesaurusController extends Controller
{
return $this->app['locales.available'];
}
/**
* @return ElasticsearchOptions
*/
private function getElasticsearchOptions()
{
return $this->app['elasticsearch.options'];
}
}

View File

@@ -3,7 +3,7 @@
namespace Alchemy\Phrasea\ControllerProvider\Api;
use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Controller\Api\V3\V3MetadatasController;
use Alchemy\Phrasea\Controller\Api\V3\V3RecordController;
use Alchemy\Phrasea\Controller\Api\V3\V3ResultHelpers;
use Alchemy\Phrasea\Controller\Api\V3\V3SearchController;
use Alchemy\Phrasea\Controller\Api\V3\V3StoriesController;
@@ -28,7 +28,7 @@ class V3 extends Api implements ControllerProviderInterface, ServiceProviderInte
));
});
$app['controller.api.v3.metadatas'] = $app->share(function (PhraseaApplication $app) {
return (new V3MetadatasController($app))
return (new V3RecordController($app))
->setJsonBodyHelper($app['json.body_helper'])
->setDispatcher($app['dispatcher'])
;
@@ -70,9 +70,9 @@ class V3 extends Api implements ControllerProviderInterface, ServiceProviderInte
$controllers->match('/search/', 'controller.api.v3.search:searchAction');
/**
* @uses V3MetadatasController::setmetadatasAction()
* @uses V3RecordController::indexAction_patch()
*/
$controllers->patch('/records/{databox_id}/{record_id}/setmetadatas/', 'controller.api.v3.metadatas:setmetadatasAction')
$controllers->patch('/records/{databox_id}/{record_id}/', 'controller.api.v3.metadatas:indexAction_patch')
->before('controller.api.v1:ensureCanAccessToRecord')
->before('controller.api.v1:ensureCanModifyRecord')
->assert('databox_id', '\d+')

View File

@@ -60,6 +60,7 @@ class Thesaurus implements ControllerProviderInterface, ServiceProviderInterface
$controllers->match('newterm.php', 'controller.thesaurus:newTerm');
$controllers->match('properties.php', 'controller.thesaurus:properties');
$controllers->match('thesaurus.php', 'controller.thesaurus:thesaurus')->bind('thesaurus_thesaurus');
$controllers->match('populate', 'controller.thesaurus:populate')->bind('thesaurus_populate');
$controllers->match('xmlhttp/accept.x.php', 'controller.thesaurus:acceptXml');
$controllers->match('xmlhttp/acceptcandidates.x.php', 'controller.thesaurus:acceptCandidatesXml');

View File

@@ -74,7 +74,6 @@ class RecordMoverJob extends AbstractJob
private function processData(Application $app, $row, $logsql)
{
/** @var databox $databox */
$databox = $app->findDataboxById($row['sbas_id']);
$rec = $databox->get_record($row['record_id']);
@@ -83,7 +82,7 @@ class RecordMoverJob extends AbstractJob
// change collection ?
if (array_key_exists('coll', $row)) {
$coll = \collection::getByCollectionId($app, $databox, $row['coll']);
$rec->move_to_collection($coll, $app['phraseanet.appbox']);
$rec->move_to_collection($coll);
if ($logsql) {
$this->log('debug', sprintf("on sbas %s move rid %s to coll %s \n", $row['sbas_id'], $row['record_id'], $coll->get_coll_id()));
}

View File

@@ -522,10 +522,11 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/**
*
* @param collection $collection
* @param appbox $appbox
* @param appbox $appbox WTF this parm is useless
* @return record_adapter
*
*/
public function move_to_collection(collection $collection, appbox $appbox)
public function move_to_collection(collection $collection, appbox $appbox = null)
{
if ($this->getCollection()->get_base_id() === $collection->get_base_id()) {
return $this;

View File

@@ -118,7 +118,7 @@ class OverviewTest extends \PhraseanetAuthenticatedWebTestCase
public function testDatafilesRouteNotAuthenticatedIsOkInPublicFeed()
{
self::$DI['app']['phraseanet.SE'] = $this->createSearchEngineMock();
self::$DI['record_5']->move_to_collection(self::$DI['collection_no_access'], self::$DI['app']['phraseanet.appbox']);
self::$DI['record_5']->move_to_collection(self::$DI['collection_no_access']);
$path = self::$DI['app']['url_generator']->generate('datafile', [
'sbas_id' => self::$DI['record_5']->get_sbas_id(),
'record_id' => self::$DI['record_5']->get_record_id(),
@@ -127,7 +127,7 @@ class OverviewTest extends \PhraseanetAuthenticatedWebTestCase
self::$DI['client']->request('GET', $path);
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
self::$DI['record_5']->move_to_collection(self::$DI['collection'], self::$DI['app']['phraseanet.appbox']);
self::$DI['record_5']->move_to_collection(self::$DI['collection']);
}
public function testDatafilesRouteNotAuthenticatedUnknownSubdef()