Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 16 | class GameController extends AbstractActionController |
||
| 17 | { |
||
| 18 | protected $options; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * @var \PlaygroundGame\Service\Game |
||
| 22 | */ |
||
| 23 | protected $adminGameService; |
||
| 24 | |||
| 25 | protected $game; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * |
||
| 29 | * @var ServiceManager |
||
| 30 | */ |
||
| 31 | protected $serviceLocator; |
||
| 32 | |||
| 33 | public function __construct(ServiceLocatorInterface $locator) |
||
| 37 | |||
| 38 | public function getServiceLocator() |
||
| 43 | |||
| 44 | public function checkGame() |
||
| 45 | { |
||
| 46 | $gameId = $this->getEvent()->getRouteMatch()->getParam('gameId'); |
||
| 47 | if (!$gameId) { |
||
| 48 | return $this->redirect()->toRoute('admin/playgroundgame/list'); |
||
| 49 | } |
||
| 50 | |||
| 51 | $game = $this->getAdminGameService()->getGameMapper()->findById($gameId); |
||
| 52 | if (!$game) { |
||
| 53 | return $this->redirect()->toRoute('admin/playgroundgame/list'); |
||
| 54 | } |
||
| 55 | $this->game = $game; |
||
| 56 | } |
||
| 57 | |||
| 58 | public function createForm($form) |
||
| 59 | { |
||
| 60 | // I use the wonderful Form Generator to create the Post & Vote form |
||
| 61 | $this->forward()->dispatch( |
||
| 62 | 'PlaygroundCore\Controller\Formgen', |
||
| 63 | array( |
||
| 64 | 'controller' => 'PlaygroundCore\Controller\Formgen', |
||
| 65 | 'action' => 'create' |
||
| 66 | ) |
||
| 67 | ); |
||
| 68 | |||
| 69 | if ($this->getRequest()->isPost()) { |
||
| 70 | $data = $this->getRequest()->getPost()->toArray(); |
||
| 71 | $form = $this->getAdminGameService()->createForm($data, $this->game, $form); |
||
| 72 | if ($form) { |
||
| 73 | $this->flashMessenger()->setNamespace('playgroundgame')->addMessage('The form was created'); |
||
| 74 | } |
||
| 75 | } |
||
| 76 | $formTemplate=''; |
||
| 77 | if ($form) { |
||
| 78 | $formTemplate = $form->getFormTemplate(); |
||
| 79 | } |
||
| 80 | |||
| 81 | return array( |
||
| 82 | 'form' => $form, |
||
| 83 | 'formTemplate' => $formTemplate, |
||
| 84 | 'gameId' => $this->game->getId(), |
||
| 85 | 'game' => $this->game, |
||
| 86 | ); |
||
| 87 | } |
||
| 88 | |||
| 89 | /** |
||
| 90 | * @param string $templatePath |
||
| 91 | * @param string $formId |
||
| 92 | */ |
||
| 93 | public function editGame($templatePath, $formId) |
||
| 94 | { |
||
| 95 | $viewModel = new ViewModel(); |
||
| 96 | $viewModel->setTemplate($templatePath); |
||
| 97 | |||
| 98 | $gameForm = new ViewModel(); |
||
| 99 | $gameForm->setTemplate('playground-game/game/game-form'); |
||
| 100 | |||
| 101 | $form = $this->getServiceLocator()->get($formId); |
||
| 102 | $form->setAttribute( |
||
| 103 | 'action', |
||
| 104 | $this->url()->fromRoute( |
||
| 105 | 'admin/playgroundgame/edit-' . $this->game->getClassType(), |
||
| 106 | array('gameId' => $this->game->getId()) |
||
| 107 | ) |
||
| 108 | ); |
||
| 109 | $form->setAttribute('method', 'post'); |
||
| 110 | |||
| 111 | if ($this->game->getFbAppId()) { |
||
| 112 | $appIds = $form->get('fbAppId')->getOption('value_options'); |
||
| 113 | $appIds[$this->game->getFbAppId()] = $this->game->getFbAppId(); |
||
| 114 | $form->get('fbAppId')->setAttribute('options', $appIds); |
||
| 115 | } |
||
| 116 | |||
| 117 | $gameOptions = $this->getAdminGameService()->getOptions(); |
||
| 118 | $gameStylesheet = $gameOptions->getMediaPath() . '/' . 'stylesheet_'. $this->game->getId(). '.css'; |
||
| 119 | View Code Duplication | if (is_file($gameStylesheet)) { |
|
| 120 | $values = $form->get('stylesheet')->getValueOptions(); |
||
| 121 | $values[$gameStylesheet] = 'Style personnalisé de ce jeu'; |
||
| 122 | |||
| 123 | $form->get('stylesheet')->setAttribute('options', $values); |
||
| 124 | } |
||
| 125 | |||
| 126 | $form->bind($this->game); |
||
| 127 | |||
| 128 | if ($this->getRequest()->isPost()) { |
||
| 129 | $data = array_replace_recursive( |
||
| 130 | $this->getRequest()->getPost()->toArray(), |
||
| 131 | $this->getRequest()->getFiles()->toArray() |
||
| 132 | ); |
||
| 133 | if (empty($data['prizes'])) { |
||
| 134 | $data['prizes'] = array(); |
||
| 135 | } |
||
| 136 | if (isset($data['drawDate']) && $data['drawDate']) { |
||
| 137 | $data['drawDate'] = \DateTime::createFromFormat('d/m/Y', $data['drawDate']); |
||
| 138 | } |
||
| 139 | $result = $this->getAdminGameService()->createOrUpdate($data, $this->game, $formId); |
||
| 140 | |||
| 141 | if ($result) { |
||
| 142 | return $this->redirect()->toRoute('admin/playgroundgame/list'); |
||
| 143 | } |
||
| 144 | } |
||
| 145 | |||
| 146 | $gameForm->setVariables(array('form' => $form, 'game' => $this->game)); |
||
| 147 | $viewModel->addChild($gameForm, 'game_form'); |
||
| 148 | |||
| 149 | return $viewModel->setVariables( |
||
| 150 | array( |
||
| 151 | 'form' => $form, |
||
| 152 | 'title' => 'Edit this game', |
||
| 153 | ) |
||
| 154 | ); |
||
| 155 | } |
||
| 156 | |||
| 157 | public function listAction() |
||
| 158 | { |
||
| 159 | $filter = $this->getEvent()->getRouteMatch()->getParam('filter'); |
||
| 160 | $type = $this->getEvent()->getRouteMatch()->getParam('type'); |
||
| 161 | |||
| 162 | $service = $this->getAdminGameService(); |
||
| 163 | $adapter = new DoctrineAdapter(new ORMPaginator($service->getQueryGamesOrderBy($type, $filter))); |
||
| 164 | $paginator = new Paginator($adapter); |
||
| 165 | $paginator->setItemCountPerPage(25); |
||
| 166 | $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p')); |
||
| 167 | |||
| 168 | foreach ($paginator as $game) { |
||
| 169 | $game->entry = $service->getEntryMapper()->countByGame($game); |
||
| 170 | } |
||
| 171 | |||
| 172 | return array( |
||
| 173 | 'games' => $paginator, |
||
| 174 | 'type' => $type, |
||
| 175 | 'filter' => $filter, |
||
| 176 | ); |
||
| 177 | } |
||
| 178 | |||
| 179 | public function entryAction() |
||
| 180 | { |
||
| 181 | $this->checkGame(); |
||
| 182 | |||
| 183 | $adapter = new DoctrineAdapter( |
||
| 184 | new LargeTablePaginator( |
||
| 185 | $this->getAdminGameService()->getEntriesQuery($this->game) |
||
| 186 | ) |
||
| 187 | ); |
||
| 188 | $paginator = new Paginator($adapter); |
||
| 189 | $paginator->setItemCountPerPage(10); |
||
| 190 | $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p')); |
||
| 191 | |||
| 192 | $header = $this->getAdminGameService()->getEntriesHeader($this->game); |
||
| 193 | $entries = $this->getAdminGameService()->getGameEntries($header, $paginator, $this->game); |
||
| 194 | |||
| 195 | return array( |
||
| 196 | 'paginator' => $paginator, |
||
| 197 | 'entries' => $entries, |
||
| 198 | 'header' => $header, |
||
| 199 | 'game' => $this->game, |
||
| 200 | 'gameId' => $this->game->getId() |
||
| 201 | ); |
||
| 202 | } |
||
| 203 | |||
| 204 | public function downloadAction() |
||
| 205 | { |
||
| 206 | $this->checkGame(); |
||
| 207 | $header = $this->getAdminGameService()->getEntriesHeader($this->game); |
||
| 208 | $query = $this->getAdminGameService()->getEntriesQuery($this->game); |
||
| 209 | |||
| 210 | $content = "\xEF\xBB\xBF"; // UTF-8 BOM |
||
| 211 | $content .= $this->getAdminGameService()->getCSV( |
||
| 212 | $this->getAdminGameService()->getGameEntries( |
||
| 213 | $header, |
||
| 214 | $query->getResult(), |
||
| 215 | $this->game |
||
| 216 | ) |
||
| 217 | ); |
||
| 218 | |||
| 219 | $response = $this->getResponse(); |
||
| 220 | $headers = $response->getHeaders(); |
||
| 221 | $headers->addHeaderLine('Content-Encoding: UTF-8'); |
||
| 222 | $headers->addHeaderLine('Content-Type', 'text/csv; charset=UTF-8'); |
||
| 223 | $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"entry.csv\""); |
||
| 224 | $headers->addHeaderLine('Accept-Ranges', 'bytes'); |
||
| 225 | $headers->addHeaderLine('Content-Length', strlen($content)); |
||
| 226 | |||
| 227 | $response->setContent($content); |
||
| 228 | |||
| 229 | return $response; |
||
| 230 | } |
||
| 231 | |||
| 232 | // Only used for Quiz and Lottery |
||
| 233 | public function drawAction() |
||
| 234 | { |
||
| 235 | $this->checkGame(); |
||
| 236 | |||
| 237 | $winningEntries = $this->getAdminGameService()->draw($this->game); |
||
| 238 | |||
| 239 | $content = "\xEF\xBB\xBF"; // UTF-8 BOM |
||
| 240 | $content .= "ID;Pseudo;Nom;Prenom;E-mail;Etat\n"; |
||
| 241 | |||
| 242 | foreach ($winningEntries as $e) { |
||
| 243 | $etat = 'gagnant'; |
||
| 244 | |||
| 245 | $content .= $e->getUser()->getId() |
||
| 246 | . ";" . $e->getUser()->getUsername() |
||
| 247 | . ";" . $e->getUser()->getLastname() |
||
| 248 | . ";" . $e->getUser()->getFirstname() |
||
| 249 | . ";" . $e->getUser()->getEmail() |
||
| 250 | . ";" . $etat |
||
| 251 | ."\n"; |
||
| 252 | } |
||
| 253 | |||
| 254 | $response = $this->getResponse(); |
||
| 255 | $headers = $response->getHeaders(); |
||
| 256 | $headers->addHeaderLine('Content-Encoding: UTF-8'); |
||
| 257 | $headers->addHeaderLine('Content-Type', 'text/csv; charset=UTF-8'); |
||
| 258 | $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"gagnants.csv\""); |
||
| 259 | $headers->addHeaderLine('Accept-Ranges', 'bytes'); |
||
| 260 | $headers->addHeaderLine('Content-Length', strlen($content)); |
||
| 261 | |||
| 262 | $response->setContent($content); |
||
| 263 | |||
| 264 | return $response; |
||
| 265 | } |
||
| 266 | |||
| 267 | /** |
||
| 268 | * This method serialize a game an export it as a txt file |
||
| 269 | * @return \Zend\Stdlib\ResponseInterface |
||
| 270 | */ |
||
| 271 | public function exportAction() |
||
| 272 | { |
||
| 273 | $this->checkGame(); |
||
| 274 | $content = serialize($this->game); |
||
| 275 | |||
| 276 | $response = $this->getResponse(); |
||
| 277 | $headers = $response->getHeaders(); |
||
| 278 | $headers->addHeaderLine('Content-Encoding: UTF-8'); |
||
| 279 | $headers->addHeaderLine('Content-Type', 'text/plain; charset=UTF-8'); |
||
| 280 | $headers->addHeaderLine( |
||
| 281 | 'Content-Disposition', |
||
| 282 | "attachment; filename=\"". $this->game->getIdentifier() .".txt\"" |
||
| 283 | ); |
||
| 284 | $headers->addHeaderLine('Accept-Ranges', 'bytes'); |
||
| 285 | $headers->addHeaderLine('Content-Length', strlen($content)); |
||
| 286 | |||
| 287 | $response->setContent($content); |
||
| 288 | |||
| 289 | return $response; |
||
| 290 | } |
||
| 291 | |||
| 292 | /** |
||
| 293 | * This method take an uploaded txt file containing a serialized game |
||
| 294 | * and persist it in the database |
||
| 295 | * @return unknown |
||
| 296 | */ |
||
| 297 | public function importAction() |
||
| 298 | { |
||
| 299 | $form = $this->getServiceLocator()->get('playgroundgame_import_form'); |
||
| 300 | $form->setAttribute('action', $this->url()->fromRoute('admin/playgroundgame/import')); |
||
| 301 | $form->setAttribute('method', 'post'); |
||
| 302 | |||
| 303 | if ($this->getRequest()->isPost()) { |
||
| 304 | $data = array_replace_recursive( |
||
| 305 | $this->getRequest()->getPost()->toArray(), |
||
| 306 | $this->getRequest()->getFiles()->toArray() |
||
| 307 | ); |
||
| 308 | |||
| 309 | if (! empty($data['import_file']['tmp_name'])) { |
||
| 310 | ErrorHandler::start(); |
||
| 311 | $game = unserialize(file_get_contents($data['import_file']['tmp_name'])); |
||
| 312 | $game->setId(null); |
||
| 313 | if ($data['slug']) { |
||
| 314 | $game->setIdentifier($data['slug']); |
||
| 315 | } |
||
| 316 | $duplicate = $this->getAdminGameService()->getGameMapper()->findByIdentifier($game->getIdentifier()); |
||
| 317 | if (!$duplicate) { |
||
| 318 | $this->getAdminGameService()->getGameMapper()->insert($game); |
||
| 319 | } |
||
| 320 | |||
| 321 | ErrorHandler::stop(true); |
||
| 322 | } |
||
| 323 | |||
| 324 | return $this->redirect()->toRoute('admin/playgroundgame/list'); |
||
| 325 | } |
||
| 326 | |||
| 327 | return array( |
||
| 328 | 'form' => $form, |
||
| 329 | ); |
||
| 330 | } |
||
| 331 | |||
| 332 | public function removeAction() |
||
| 333 | { |
||
| 334 | $this->checkGame(); |
||
| 335 | |||
| 336 | try { |
||
| 337 | $this->getAdminGameService()->getGameMapper()->remove($this->game); |
||
| 338 | $this->flashMessenger()->setNamespace('playgroundgame')->addMessage('The game has been edited'); |
||
| 339 | } catch (\Doctrine\DBAL\DBALException $e) { |
||
| 340 | $this->flashMessenger()->setNamespace('playgroundgame')->addMessage( |
||
| 341 | 'Il y a déjà eu des participants à ce jeu. Vous ne pouvez plus le supprimer' |
||
| 342 | ); |
||
| 343 | } |
||
| 344 | |||
| 345 | return $this->redirect()->toRoute('admin/playgroundgame/list'); |
||
| 346 | } |
||
| 347 | |||
| 348 | public function setActiveAction() |
||
| 349 | { |
||
| 350 | $this->checkGame(); |
||
| 351 | |||
| 352 | $this->game->setActive(!$this->game->getActive()); |
||
| 353 | $this->getAdminGameService()->getGameMapper()->update($this->game); |
||
| 354 | |||
| 355 | return $this->redirect()->toRoute('admin/playgroundgame/list'); |
||
| 356 | } |
||
| 357 | |||
| 358 | public function formAction() |
||
| 359 | { |
||
| 360 | $this->checkGame(); |
||
| 361 | |||
| 362 | $form = $this->game->getPlayerForm(); |
||
| 363 | |||
| 364 | return $this->createForm($form); |
||
| 365 | } |
||
| 366 | |||
| 367 | public function setOptions(ModuleOptions $options) |
||
| 368 | { |
||
| 369 | $this->options = $options; |
||
| 370 | |||
| 371 | return $this; |
||
| 372 | } |
||
| 373 | |||
| 374 | public function getOptions() |
||
| 375 | { |
||
| 376 | if (!$this->options instanceof ModuleOptions) { |
||
| 377 | $this->setOptions($this->getServiceLocator()->get('playgroundgame_module_options')); |
||
| 378 | } |
||
| 379 | |||
| 380 | return $this->options; |
||
| 381 | } |
||
| 382 | |||
| 383 | public function getAdminGameService() |
||
| 391 | |||
| 392 | public function setAdminGameService(AdminGameService $adminGameService) |
||
| 398 | } |
||
| 399 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..