/** Crosswords management. */ function crossword($crossword = null, $operation = null) { if ('save' === $operation) { OutputModes('ajax'); } if (!CheckPermissions('office')) { return; } if (null !== $crossword && is_numeric($crossword)) { $crossword = (int) $crossword; $crosswords = $this->crosswords_model->GetCrosswords($crossword); if (count($crosswords) === 0) { show_404(); } $crossword_info = $crosswords[0]; $this->load->model('permissions_model'); $data = array('Permissions' => array('modify' => $this->permissions_model->hasUserPermission('CROSSWORD_MODIFY'), 'stats_basic' => $this->permissions_model->hasUserPermission('CROSSWORD_STATS_BASIC')), 'Crossword' => &$crossword_info); if (null === $operation) { if (!CheckRolePermissions('CROSSWORD_VIEW')) { return; } $puzzle = 0; $worked = $this->crosswords_model->LoadCrossword($crossword_info['id'], $puzzle); if (!$worked) { show_404(); } $crosswordView = new CrosswordView($puzzle); $crosswordView->setClueTypes($crossword_info['has_quick_clues'], $crossword_info['has_cryptic_clues']); $crosswordView->setReadOnly(true, true); $data['Grid'] =& $crosswordView; $data['Tips'] = new CrosswordTipsList(null, $crossword_info['id'], true, false); $this->pages_model->SetPageCode('crosswords_office_xword_view'); $this->main_frame->SetContentSimple('crosswords/office/crossword_view', $data); } else { if ('save' === $operation) { if (!CheckRolePermissions('CROSSWORD_VIEW', 'CROSSWORD_MODIFY')) { return; } if (isset($_POST['xw']['save'])) { $puzzle = new CrosswordPuzzle(); $worked = $puzzle->importData($_POST['xw']); if ($worked) { $this->crosswords_model->SaveCrossword($crossword, $puzzle); $status = 'success'; } else { $this->main_frame->Error(array('class' => 'error', 'text' => 'Invalid crossword data.')); $status = 'fail'; } } else { $this->main_frame->Error(array('class' => 'error', 'text' => 'Unable to edit crossword.')); $status = 'fail'; } $root = array('_tag' => 'crossword', 'status' => $status); $this->main_frame->SetXml($root); $this->main_frame->Load(); return; } else { if ('edit' === $operation) { if (!CheckRolePermissions('CROSSWORD_VIEW', 'CROSSWORD_MODIFY')) { return; } $this->pages_model->SetPageCode('crosswords_office_xword_edit'); $this->load->helper('input_date'); $this->load->helper('input_progress'); $puzzle = 0; $worked = $this->crosswords_model->LoadCrossword($crossword, $puzzle); if (!$worked) { $puzzle = new CrosswordPuzzle(13, 13); } $crosswordView = new CrosswordView($puzzle, true); $data = array(); // MAIN CONFIGURATION $config = new InputInterfaces(); $quick_clues_interface = new InputCheckboxInterface('has_quick_clues', $crossword_info['has_quick_clues']); $config->Add('Quick clues', $quick_clues_interface); $cryptic_clues_interface = new InputCheckboxInterface('has_cryptic_clues', $crossword_info['has_cryptic_clues']); $config->Add('Cryptic Clues', $cryptic_clues_interface); $categories = $this->crosswords_model->GetAllCategories(); $category_names = array(); foreach ($categories as $id => $category) { $category_names[$id] = $category['name']; } $category_interface = new InputSelectInterface('category_id', $crossword_info['category_id']); $category_interface->SetOptions($category_names); $config->Add('Category', $category_interface); $layouts = $this->crosswords_model->GetAllLayouts(); $layout_names = array(); foreach ($layouts as $id => $layout) { $layout_names[$id] = $layout['name']; } $layout_interface = new InputSelectInterface('layout_id', $crossword_info['layout_id']); $layout_interface->SetOptions($layout_names); $config->Add('Layout', $layout_interface); $deadline_interface = new InputDateInterface('deadline', $crossword_info['deadline'], true); $config->Add('Deadline', $deadline_interface); $publication_interface = new InputDateInterface('publication', $crossword_info['publication'], true); $config->Add('Publication', $publication_interface); $expiry_interface = new InputDateInterface('expiry', $crossword_info['expiry'], true); $config->Add('Expiry', $expiry_interface); $winners_value = $crossword_info['winners']; $winners_interface = new InputIntInterface('winners', $winners_value, $winners_value > 0); $winners_interface->SetRange(1, 100); $config->Add('Winners', $winners_interface); $completeness_interface = new InputProgressInterface('completeness', $crossword_info['completeness']); $config->Add('Progress', $completeness_interface); $authors_interface = new InputSelectInterface('authors', $crossword_info['author_ids']); $authors = $this->crosswords_model->GetAllAuthors(); $author_options = array(); foreach ($authors as $author) { $author_options[(int) $author['id']] = $author['fullname']; } foreach ($crossword_info['authors'] as $author) { if (!isset($author_options[$author['id']])) { $author_options[$author['id']] = $author['fullname']; } } $authors_interface->SetOptions($author_options); $config->Add('Authors', $authors_interface); // VALIDATION $num_errors = $config->Validate(); if (0 == $num_errors && $config->Updated()) { $values = $config->ChangedValues(); $error = false; if (count($values) == 0) { $this->messages->AddMessage('information', "You did not make any changes"); $error = true; } // Apply rules to changes here $integrated_values = $crossword_info; foreach ($values as $id => $value) { $integrated_values[$id] = $value; } // can't have deadline after publishing if ($integrated_values['deadline'] !== null && $integrated_values['publication'] !== null && $integrated_values['deadline'] > $integrated_values['publication']) { $this->messages->AddMessage('error', 'Deadline should not be set after publication'); $error = true; } // can't have expiry before publishing if ($integrated_values['publication'] !== null && $integrated_values['expiry'] !== null && $integrated_values['publication'] > $integrated_values['expiry']) { $this->messages->AddMessage('error', 'Expiry should not be set before publication'); $error = true; } if (!$error) { if (isset($values['authors'])) { $authors = $values['authors']; $values['authors'] = array(); foreach ($authors as $author_id) { $values['authors'][(int) $author_id] = array('id' => (int) $author_id, 'fullname' => $author_options[(int) $author_id]); } } $values['id'] = $crossword_info['id']; if (!$this->crosswords_model->UpdateCrossword($values)) { $this->messages->AddMessage('error', 'Changes could not be saved'); } else { $this->messages->AddMessage('success', 'Changes have been saved successfully'); foreach ($values as $id => $value) { $crossword_info[$id] = $value; } } } } // Which clues are enabled may have just changed $crosswordView->setClueTypes($crossword_info['has_quick_clues'], $crossword_info['has_cryptic_clues']); $data['Configuration'] =& $config; $data['Tips'] = new CrosswordTipsList(null, $crossword_info['id'], true); $data['Grid'] =& $crosswordView; $data['Paths'] = array('view' => site_url("office/crosswords/crossword/{$crossword}"), 'save' => site_url("office/crosswords/crossword/{$crossword}/save")); $this->main_frame->SetContentSimple('crosswords/office/crossword_edit', $data); } else { if ('stats' === $operation) { if (!CheckRolePermissions('CROSSWORD_STATS_BASIC')) { return; } // find information about this crossword $data['Stats'] = $this->crosswords_model->CalculateStats($crossword_info['id'], array('saves', 'save_users')); $data['Stats']['winners'] = $crossword_info['winners_so_far']; $data['StatLabels'] = array('save_users' => 'Number of users who have attempted crossword (based on saves)', 'save_mean_per_user' => 'Mean number of saves per user (approx 30 secs between saves)', 'winners' => 'Number of winners'); $this->main_frame->SetContentSimple('crosswords/office/crossword_stats', $data); } elseif ($operation == 'preview') { if (!CheckRolePermissions('CROSSWORD_VIEW')) { return; } $this->crosswords_model->GetCrosswordThumbnail($crossword); return; } else { show_404(); } } } } } else { show_404(); } $this->main_frame->Load(); }
function crossword_by_id($id = null, $operation = null, $comment_include = null) { if ($operation == 'ajax') { OutputModes('ajax'); } if (!CheckPermissions('public')) { return; } $loggedIn = $this->user_auth->isLoggedIn; if (null === $id || !is_numeric($id)) { show_404(); } $id = (int) $id; $crossword = $this->crosswords_model->GetCrosswords($id, null, null, null, true, null); if (count($crossword) == 0) { show_404(); } $crossword = $crossword[0]; $puzzle = 0; $worked = $this->crosswords_model->LoadCrossword($crossword['id'], $puzzle); if (!$worked) { show_404(); } // WARNING: SOLUTION NOT NECESSARILY CLEARED if (null === $operation || 'view' === $operation) { $puzzle->grid()->clearSolutions(); $crosswordView = new CrosswordView($puzzle); $crosswordView->setClueTypes($crossword['has_quick_clues'], $crossword['has_cryptic_clues']); if (!$loggedIn) { $crosswordView->setReadOnly(!$crossword['expired']); } else { $success = $this->crosswords_model->LoadCrosswordVersion($crossword['id'], $this->user_auth->entityId, $puzzle); } // Comment thread $comments_thread = null; $comments_require_expiration = false; if ((!$comments_require_expiration || $crossword['expired']) && is_numeric($crossword['public_thread_id'])) { $this->load->library('comment_views'); $this->comment_views->SetUri('/crosswords/' . $crossword['id'] . '/view/'); $comments_thread = $this->comment_views->CreateStandard((int) $crossword['public_thread_id'], $comment_include); } $data = array(); $data['Crossword'] =& $crossword; $data['Winners'] = $this->crosswords_model->GetWinners($crossword['id']); $data['Grid'] =& $crosswordView; $data['LoggedIn'] = $loggedIn; $data['Paths'] = array('ajax' => site_url('/crosswords/' . $crossword['id'] . '/ajax')); $data['Tips'] = new CrosswordTipsList(null, $crossword['id']); $data['Comments'] = $comments_thread; $data['Links'] = array('more crosswords in the "' . $crossword['category_name'] . '" category' => site_url('crosswords/' . $crossword['category_short_name']), 'crosswords home' => site_url('crosswords')); $data['ShareUrl'] = $_SERVER['SERVER_NAME'] . '/crosswords/' . $crossword['id']; $this->main_frame->SetContentSimple('crosswords/crossword', $data); /// @todo Use pages interface $pub = new Academic_time($crossword['publication']); $this->main_frame->SetTitle('Crossword ' . $pub->Format('D ') . $pub->AcademicTermNameUnique() . ' week ' . $pub->AcademicWeek()); $this->main_frame->AddDescription('Online crossword'); $this->main_frame->SetMainImage(site_url('crosswords/' . $crossword['id'] . '/preview')); } elseif ($operation == 'ajax') { $op2 = $comment_include; $root = array('_tag' => 'crossword'); if ($op2 == 'winners') { $root['expired'] = $crossword['expired'] ? "yes" : "no"; $root['positions'] = $crossword['winners']; $winners = $this->crosswords_model->GetWinners($crossword['id']); $root['winners'] = array(); foreach ($winners as $position => &$winner) { $root['winners'][] = array('_tag' => 'winner', '_attr' => array('position' => $position), 'name' => $winner['firstname'] . ' ' . $winner['surname']); } } elseif ($op2 == 'solution') { $root['solution'] = array('_attr' => array('available' => $crossword['expired'] ? "yes" : "no")); if ($crossword['expired']) { $root['solution']['grid'] = array(); $grid =& $puzzle->grid(); $height = $grid->height(); $width = $grid->width(); for ($y = 0; $y < $height; ++$y) { for ($x = 0; $x < $width; ++$x) { $state = $grid->cellState($x, $y); if (is_string($state)) { $root['solution']['grid'][] = array('_tag' => 'letter', '_attr' => array('x' => $x, 'y' => $y), $state); } } } } } elseif (!$loggedIn) { $this->main_frame->Error(array('class' => 'error', 'text' => 'Not logged in.')); $root['status'] = 'fail'; } else { $puzzle->grid()->clearSolutions(); $worked = $puzzle->importGrid($_POST['xw']); if ($worked) { // Saving (and autosaving) if (isset($_POST['xw']['save']) || isset($_POST['xw']['autosave'])) { $success = $this->crosswords_model->SaveCrosswordVersion($crossword['id'], $this->user_auth->entityId, $puzzle); $root['status'] = $success ? 'success' : 'fail'; if (!$success) { $this->main_frame->Error(array('class' => 'error', 'text' => 'Unable to save crossword.')); } } elseif (isset($_POST['xw']['submit'])) { $root['status'] = 'success'; $correct = $puzzle->isCorrect(); $root['mark'] = $correct ? 'correct' : 'incorrect'; $winner = false; if ($correct) { $winner = $this->crosswords_model->AddWinner($crossword['id'], $this->user_auth->entityId); } $root['winner'] = $winner ? 'yes' : 'no'; } else { $this->main_frame->Error(array('class' => 'error', 'text' => 'Unable to edit crossword.')); $root['status'] = 'fail'; } } else { $this->main_frame->Error(array('class' => 'error', 'text' => 'Invalid crossword data.')); $root['status'] = 'fail'; } } $this->main_frame->SetXml($root); } elseif ($operation == 'preview') { $this->crosswords_model->GetCrosswordThumbnail($crossword['id']); return; } else { show_404(); } $this->main_frame->Load(); }