SearchIndexController.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2017 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  private $NODES_PER_CALL = 1;
52 
53  // the number of nodes to index before optimizing the index
54  private static $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', $this->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  $this->search->addToIndex($obj);
155  }
156  }
157  $this->search->commitIndex(false);
158 
159  if ($this->getStepNumber() == $this->getNumberOfSteps()) {
160  $this->addWorkPackage($this->getMessage()->getText('Optimizing index'),
161  1, [0], 'optimize');
162  }
163  }
164 
165  /**
166  * Optimize the search index
167  * @param $oids The oids to process
168  * @note This is a callback method called on a matching work package @see BatchController::addWorkPackage()
169  */
170  protected function optimize($oids) {
171  $this->search->optimizeIndex();
172  }
173  // PROTECTED REGION END
174 }
175 ?>
Response holds the response values that are used as output from Controller instances.
Definition: Response.php:20
Localization defines the interface for storing localized entity instances and retrieving them back...
getMessage()
Get the Message instance.
Definition: Controller.php:311
addWorkPackage($name, $size, $oids, $callback, $args=null)
Add a work package to session.
__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.
getStepNumber()
Get the number of the current step (1..number of steps).
collect($types)
Collect all oids of the given types.
IndexedSearch implementations are used to search entity objects in a search index.
Message is used to get localized messages to be used in the user interface.
Definition: Message.php:23
getAction()
Get the name of the action.
Session is the interface for session implementations and defines access to session variables...
Definition: Session.php:19
Request holds the request values that are used as input to Controller instances.
Definition: Request.php:18
BatchController is used to process complex, longer running actions, that need to be divided into seve...
initialize(Request $request, Response $response)
hasValue($name)
Check for existence of a value.
PermissionManager implementations are used to handle all authorization requests.
Implementations of Configuration give access to the application configuration.
Application controllers.
Definition: namespaces.php:3
setValue($name, $value)
Set a value.
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
ActionMapper implementations are responsible for instantiating and executing Controllers based on the...
getRequestValue($name)
Get a value from the initial request.
PersistenceFacade defines the interface for PersistenceFacade implementations.
Search implementations are used to search entity objects.
Definition: Search.php:21
getNumberOfSteps()
Get the number of steps to process.
index($oids)
Create the lucene index from the given objects.
getPersistenceFacade()
Get the PersistenceFacade instance.
Definition: Controller.php:279