SearchIndexController.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2020 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
12 
26 
27 /**
28  * SearchIndexController creates a Lucene index from the complete datastore.
29  *
30  * The controller supports the following actions:
31  *
32  * <div class="controller-action">
33  * <div> __Action__ _default_ </div>
34  * <div>
35  * Create the index.
36  * | Parameter | Description
37  * |------------------------|-------------------------
38  * | _in_ `nodesPerCall` | The number of nodes to process in one call (default: 10)
39  * </div>
40  * </div>
41  *
42  * For additional actions and parameters see [BatchController actions](@ref BatchController).
43  *
44  * @author ingo herwig <ingo@wemove.com>
45  */
47 
48  private $search = null;
49 
50  // default values, maybe overriden by corresponding request values (see above)
51  const NODES_PER_CALL = 1;
52 
53  // the number of nodes to index before optimizing the index
54  const OPTIMIZE_FREQ = 50;
55 
56  /**
57  * Constructor
58  * @param $session
59  * @param $persistenceFacade
60  * @param $permissionManager
61  * @param $actionMapper
62  * @param $localization
63  * @param $message
64  * @param $configuration
65  * @param $search
66  */
67  public function __construct(Session $session,
68  PersistenceFacade $persistenceFacade,
69  PermissionManager $permissionManager,
70  ActionMapper $actionMapper,
71  Localization $localization,
72  Message $message,
73  Configuration $configuration,
74  Search $search) {
75  parent::__construct($session, $persistenceFacade, $permissionManager,
76  $actionMapper, $localization, $message, $configuration);
77  $this->search = $search;
78  }
79 
80  /**
81  * @see Controller::initialize()
82  */
83  public function initialize(Request $request, Response $response) {
84  // initialize controller
85  if ($request->getAction() != 'continue') {
86  // set defaults (will be stored with first request)
87  if (!$request->hasValue('nodesPerCall')) {
88  $request->setValue('nodesPerCall', self::NODES_PER_CALL);
89  }
90  }
91  // initialize parent controller after default request values are set
92  parent::initialize($request, $response);
93  }
94 
95  /**
96  * @see BatchController::getWorkPackage()
97  */
98  protected function getWorkPackage($number) {
99  if ($number == 0) {
100  if ($this->search instanceof IndexedSearch) {
101  // get all types to index
102  $types = [];
103  $persistenceFacade = $this->getPersistenceFacade();
104  foreach ($persistenceFacade->getKnownTypes() as $type) {
105  $tpl = $persistenceFacade->create($type);
106  if ($this->search->isSearchable($tpl)) {
107  $types[] = $type;
108  }
109  }
110  $this->search->resetIndex();
111  return ['name' => $this->getMessage()->getText('Collect objects'),
112  'size' => 1, 'oids' => $types, 'callback' => 'collect'];
113  }
114  else {
115  // no index to be updated
116  return null;
117  }
118  }
119  else {
120  return null;
121  }
122  }
123 
124  /**
125  * Collect all oids of the given types
126  * @param $types The types to process
127  * @note This is a callback method called on a matching work package @see BatchController::addWorkPackage()
128  */
129  protected function collect($types) {
130  $persistenceFacade = $this->getPersistenceFacade();
131  $nodesPerCall = $this->getRequestValue('nodesPerCall');
132  foreach ($types as $type) {
133  $oids = $persistenceFacade->getOIDs($type);
134  $oidLists = array_chunk($oids, self::OPTIMIZE_FREQ);
135  for ($i=0, $count=sizeof($oidLists); $i<$count; $i++) {
136  $this->addWorkPackage($this->getMessage()->getText('Indexing %0% %1% objects, starting from %2%., ', [sizeof($oids), $type, ($i*self::OPTIMIZE_FREQ+1)]),
137  $nodesPerCall, $oidLists[$i], 'index');
138  $this->addWorkPackage($this->getMessage()->getText('Optimizing index'),
139  1, [0], 'optimize');
140  }
141  }
142  }
143 
144  /**
145  * Create the lucene index from the given objects
146  * @param $oids The oids to process
147  * @note This is a callback method called on a matching work package @see BatchController::addWorkPackage()
148  */
149  protected function index($oids) {
150  $persistenceFacade = $this->getPersistenceFacade();
151  foreach($oids as $oid) {
152  if (ObjectId::isValid($oid)) {
153  $obj = $persistenceFacade->load($oid);
154  if ($obj) {
155  $this->search->addToIndex($obj);
156  }
157  }
158  }
159  $this->search->commitIndex(false);
160 
161  if ($this->getStepNumber() == $this->getNumberOfSteps()) {
162  $this->addWorkPackage($this->getMessage()->getText('Optimizing index'),
163  1, [0], 'optimize');
164  }
165  }
166 
167  /**
168  * Optimize the search index
169  * @param $oids The oids to process
170  * @note This is a callback method called on a matching work package @see BatchController::addWorkPackage()
171  */
172  protected function optimize($oids) {
173  $this->search->optimizeIndex();
174  }
175  // PROTECTED REGION END
176 }
177 ?>
Session is the interface for session implementations and defines access to session variables.
Definition: Session.php:19
Response holds the response values that are used as output from Controller instances.
Definition: Response.php:20
Request holds the request values that are used as input to Controller instances.
Definition: Request.php:18
__construct(Session $session, PersistenceFacade $persistenceFacade, PermissionManager $permissionManager, ActionMapper $actionMapper, Localization $localization, Message $message, Configuration $configuration, Search $search)
Constructor.
SearchIndexController creates a Lucene index from the complete datastore.
collect($types)
Collect all oids of the given types.
hasValue($name)
Check for existence of a value.
index($oids)
Create the lucene index from the given objects.
getStepNumber()
Get the number of the current step (1..number of steps).
IndexedSearch implementations are used to search entity objects in a search index.
Search implementations are used to search entity objects.
Definition: Search.php:21
ObjectId is the unique identifier of an object.
Definition: ObjectId.php:27
getAction()
Get the name of the action.
Implementations of Configuration give access to the application configuration.
getMessage()
Get the Message instance.
Definition: Controller.php:315
PersistenceFacade defines the interface for PersistenceFacade implementations.
getRequestValue($name)
Get a value from the initial request.
getPersistenceFacade()
Get the PersistenceFacade instance.
Definition: Controller.php:283
setValue($name, $value)
Set a value.
Application controllers.
Definition: namespaces.php:3
BatchController is used to process complex, longer running actions, that need to be divided into seve...
addWorkPackage($name, $size, array $oids, $callback, $args=null)
Add a work package to session.
ActionMapper implementations are responsible for instantiating and executing Controllers based on the...
static isValid($oid)
Check if a serialized ObjectId has a valid syntax, the type is known and if the number of primary key...
Definition: ObjectId.php:122
initialize(Request $request, Response $response)
PermissionManager implementations are used to handle all authorization requests.
getNumberOfSteps()
Get the number of steps to process.
Localization defines the interface for storing localized entity instances and retrieving them back.
Message is used to get localized messages to be used in the user interface.
Definition: Message.php:23