public function build_edition($current_edition) { $output = ''; $editions = array(); // Since we don't have any conditions in our template, we have to build // html here. if (!isset($current_edition)) { $current_edition = EDITION_ID; } try { $edition_object = new Edition(); $editions = $edition_object->all(); } catch (Exception $error) { // It's ok if we get an error here, as this happens before we have a database setup. $editions = array(); } if ($editions && count($editions) > 1) { $output = '<select name="edition_id" id="edition_id">'; $output .= '<option value="">Search All Editions</option>'; foreach ($editions as $edition) { $output .= '<option value="' . $edition->id . '"'; if ($edition->id == $current_edition) { $output .= ' selected="selected"'; } $output .= '>' . $edition->name; if ($edition->current) { $output .= ' (current)'; } $output .= '</option>'; } $output .= '</select>'; } elseif (count($editions) == 1) { $output .= '<input type="hidden" name="edition_id" value="' . $editions[0]->id . '">'; } return $output; }
/** * The page that displays a list of editions. * * PHP version 5 * * @license http://www.gnu.org/licenses/gpl.html GPL 3 * @version 0.9 * @link http://www.statedecoded.com/ * @since 0.1 */ /* * Setup the edition object. */ require_once INCLUDE_PATH . 'class.Edition.inc.php'; global $db; $edition_obj = new Edition(array('db' => $db)); $permalink_obj = new Permalink(array('db' => $db)); /* * Create a container for our content. */ $content = new Content(); $content->set('browser_title', 'Editions'); $content->set('page_title', '<h2>Editions</h2>'); /* * Get editions. */ $editions = $edition_obj->all(); $body = '<p> These are the available editions of the code. </p>'; $body .= '<ol class="edition-list">';
public static function currentCategories() { if (!self::$_currentCategories) { self::$_currentCategories = self::find()->where(['edition_id' => Edition::getCurrentEdId()])->select(['id', 'source_id', 'parent_sid', 'name'])->asArray()->indexBy('source_id')->all(); } return self::$_currentCategories; }
/** * Recurse through all subsections to build permalink data. */ public function build_permalink_subsections($edition_id, $parent_id = null) { $edition_obj = new Edition(array('db' => $this->db)); $edition = $edition_obj->find_by_id($edition_id); /* * If we don't have a parent, set the base url. * We only want to do this once. */ if (!isset($parent_id)) { /* * By default, the actual permalink is preferred. */ $preferred = 1; /* * If this is the current edition, add links to the urls * without the edition slug. This becomes the preferred * link url. */ if ($edition->current) { $insert_data = array(':object_type' => 'structure', ':relational_id' => '', ':identifier' => '', ':token' => '', ':url' => '/browse/', ':edition_id' => $edition_id, ':preferred' => $preferred, ':permalink' => 0); $this->permalink_obj->create($insert_data); $preferred = 0; } $insert_data = array(':object_type' => 'structure', ':relational_id' => '', ':identifier' => '', ':token' => '', ':url' => '/' . $edition->slug . '/', ':edition_id' => $edition_id, ':preferred' => $preferred, ':permalink' => 1); $this->permalink_obj->create($insert_data); } $structure_sql = 'SELECT structure_unified.* FROM structure LEFT JOIN structure_unified ON structure.id = structure_unified.s1_id WHERE structure.edition_id = :edition_id'; /* * We use prepared statements for efficiency. As a result, * we need to keep an array of our arguments rather than * hardcoding them in the SQL. */ $structure_args = array(':edition_id' => $edition_id); if (isset($parent_id)) { $structure_sql .= ' AND parent_id = :parent_id'; $structure_args[':parent_id'] = $parent_id; } else { $structure_sql .= ' AND parent_id IS NULL'; } $structure_statement = $this->db->prepare($structure_sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); $structure_statement->execute($structure_args); /* * Get results as an array to save memory */ while ($item = $structure_statement->fetch(PDO::FETCH_ASSOC)) { /* * Figure out the URL for this structural unit by iterating through the "identifier" * columns in this row. */ $identifier_parts = array(); foreach ($item as $key => $value) { if (preg_match('/s[0-9]_identifier/', $key) == 1) { /* * Higher-level structural elements (e.g., titles) will have blank columns in * structure_unified, so we want to omit any blank values. Because a valid * structural unit identifier is "0" (Virginia does this), we check the string * length, rather than using empty(). */ if (strlen($value) > 0) { $identifier_parts[] = urlencode($value); } } } $identifier_parts = array_reverse($identifier_parts); $structure_token = implode('/', $identifier_parts); /* * Insert the structure */ /* * By default, the actual permalink is preferred. */ $preferred = 1; /* * If this is the current edition, add links to the urls * without the edition slug. This becomes the preferred * link url. */ if ($edition->current) { $insert_data = array(':object_type' => 'structure', ':relational_id' => $item['s1_id'], ':identifier' => $item['s1_identifier'], ':token' => $structure_token, ':url' => '/' . $structure_token . '/', ':edition_id' => $edition_id, ':preferred' => 1, ':permalink' => 0); $this->permalink_obj->create($insert_data); $preferred = 0; } /* * Insert actual permalinks. */ $insert_data = array(':object_type' => 'structure', ':relational_id' => $item['s1_id'], ':identifier' => $item['s1_identifier'], ':token' => $structure_token, ':url' => '/' . $edition->slug . '/' . $structure_token . '/', ':edition_id' => $edition_id, ':preferred' => $preferred, ':permalink' => 1); $this->permalink_obj->create($insert_data); /* * Now we can use our data to build the child law identifiers */ if (INCLUDES_REPEALED !== TRUE) { $laws_sql = ' SELECT id, structure_id, section AS section_number, catch_line FROM laws WHERE structure_id = :s_id AND laws.edition_id = :edition_id ORDER BY order_by, section'; } else { $laws_sql = ' SELECT laws.id, laws.structure_id, laws.section AS section_number, laws.catch_line FROM laws LEFT OUTER JOIN laws_meta ON laws_meta.law_id = laws.id AND laws_meta.meta_key = "repealed" WHERE structure_id = :s_id AND (laws_meta.meta_value = "n" OR laws_meta.meta_value IS NULL) AND laws.edition_id = :edition_id ORDER BY order_by, section'; } $laws_statement = $this->db->prepare($laws_sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); $laws_sql_args = array(':s_id' => $item['s1_id'], ':edition_id' => $edition_id); $laws_statement->execute($laws_sql_args); while ($law = $laws_statement->fetch(PDO::FETCH_ASSOC)) { /* * Note that we descend from our most-preferred url option * to our least, depending on what flags have been set. */ $preferred = 1; if (!defined('LAW_LONG_URLS') || LAW_LONG_URLS === FALSE) { /* * Current-and-short is the most-preferred (shortest) url. */ if ($edition->current) { $insert_data = array(':object_type' => 'law', ':relational_id' => $law['id'], ':identifier' => $law['section_number'], ':token' => $structure_token . '/' . $law['section_number'], ':url' => '/' . $law['section_number'] . '/', ':edition_id' => $edition_id, ':permalink' => 0, ':preferred' => 1); $this->permalink_obj->create($insert_data); $preferred = 0; } /* * If this is not-current, then short is the most-preferred. */ $insert_data = array(':object_type' => 'law', ':relational_id' => $law['id'], ':identifier' => $law['section_number'], ':token' => $structure_token . '/' . $law['section_number'], ':url' => '/' . $edition->slug . '/' . $law['section_number'] . '/', ':edition_id' => $edition_id, ':permalink' => 0, ':preferred' => $preferred); $this->permalink_obj->create($insert_data); $preferred = 0; } /* * Long and current is our third choice. */ if ($edition->current) { $insert_data = array(':object_type' => 'law', ':relational_id' => $law['id'], ':identifier' => $law['section_number'], ':token' => $structure_token . '/' . $law['section_number'], ':url' => '/' . $structure_token . '/' . $law['section_number'] . '/', ':edition_id' => $edition_id, ':permalink' => 0, ':preferred' => $preferred); $this->permalink_obj->create($insert_data); $preferred = 0; } /* * Failing everything else, use the super-long url. */ $insert_data = array(':object_type' => 'law', ':relational_id' => $law['id'], ':identifier' => $law['section_number'], ':token' => $structure_token . '/' . $law['section_number'], ':url' => '/' . $edition->slug . '/' . $structure_token . '/' . $law['section_number'] . '/', ':edition_id' => $edition_id, ':permalink' => 1, ':preferred' => $preferred); $this->permalink_obj->create($insert_data); } $this->build_permalink_subsections($edition_id, $item['s1_id']); } }
/** * The page that displays an individual law. * * PHP version 5 * * @license http://www.gnu.org/licenses/gpl.html GPL 3 * @version 0.9 * @link http://www.statedecoded.com/ * @since 0.1 */ /* * Setup the edition object. */ require_once INCLUDE_PATH . 'class.Edition.inc.php'; global $db; $edition = new Edition(array('db' => $db)); /* * Create a new instance of Law. */ $laws = new Law(); if (isset($args['edition_id'])) { $laws->edition_id = $args['edition_id']; } /* * Use the ID passed to look up the law. */ if (isset($args['relational_id'])) { $laws->law_id = filter_var($args['relational_id'], FILTER_SANITIZE_STRING); /* * Retrieve a copy of the law. */
/** * The page that displays an individual structural unit. * * PHP version 5 * * @license http://www.gnu.org/licenses/gpl.html GPL 3 * @version 0.9 * @link http://www.statedecoded.com/ * @since 0.1 */ /* * Setup the edition object. */ require_once INCLUDE_PATH . 'class.Edition.inc.php'; global $db; $edition = new Edition(array('db' => $db)); /* * If no identifier has been specified, explicitly make it a null variable. This is when the request * is for the top level -- that is, a listing of the fundamental units of the code (e.g., titles). */ if (!isset($args['relational_id']) || empty($args['relational_id'])) { $structure_id = ''; } else { /* * Localize the identifier, filtering out unsafe characters. */ $structure_id = filter_var($args['relational_id'], FILTER_SANITIZE_STRING); } /* * Create a new instance of the class that handles information about individual laws. */
function show_admin_forms($args = array()) { global $db; $edition = new Edition(array('db' => $db)); try { $editions = $edition->all(); } catch (Exception $exception) { $editions = FALSE; } if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) { $base_url = 'https://'; } else { $edition_url_base = 'http://'; } $edition_url_base .= $_SERVER['SERVER_NAME']; if ($_SERVER['SERVER_PORT'] != 80) { $edition_url_base .= ':' . $_SERVER['SERVER_PORT']; } $edition_url_base .= '/'; $body = '<p>What do you want to do?</p> <form method="post" action="/admin/?page=parse&noframe=1"> <h3>Import Data</h3>'; if (isset($args['import_errors'])) { $body .= '<div class="errors"> Please fix the following errors: <ul>'; foreach ($args['import_errors'] as $error) { $body .= '<li>' . $error . '</li>'; } $body .= '</div>'; } $body .= '<p>This will import all data files from your data directory: <span class="code">' . IMPORT_DATA_DIR . '</span></p> <input type="hidden" name="action" value="parse" /> <div class="option"> <input type="radio" class="radio" name="edition_option" id="edition_option_new" value="new"'; if (!$editions || $args['edition_option'] == 'existing') { $body .= 'checked="checked"'; } $body .= '/> <label for="edition_option_new">I want to create a new edition of the laws.</label> <div class="suboption"> <label for="new_edition_name">I want to call this edition</label> <div> <input type="text" class="text" name="new_edition_name" id="new_edition_name" placeholder="' . date('Y-m') . '" value="' . (isset($args['new_edition_name']) ? $args['new_edition_name'] : '') . '" /> </div> </div> <div class="suboption"> <label for="new_edition_slug">. . .</option> and the URL for this edition will be</label> <div class="edition_url">' . $edition_url_base . ' <input type="text" class="text" name="new_edition_slug" id="new_edition_slug" placeholder="' . date('Y-m') . '" value="' . (isset($args['new_edition_slug']) ? $args['new_edition_slug'] : '') . '" /> / </div> <p class="note">Note: In general, try to only use letters, numbers, and hyphens, and avoid using anything that might conflict with a section number or structure name.</p> </div> </div> <div class="option"> <input type="radio" class="radio" name="edition_option" id="edition_option_existing" value="existing"'; if (!isset($editions) || $editions === FALSE) { $body .= 'disabled="disabled"'; } elseif ($args['edition_option'] == 'existing') { $body .= 'checked="checked"'; } $body .= '/><label for="edition_option_existing">I want to update an existing edition of the laws.</label>'; if ($editions !== FALSE) { $body .= '<div class="suboption"> <p>This will remove all existing data in this edition.</p> <select name="edition" value="edition"> <option value="">Choose Edition . . .</option>'; foreach ($editions as $edition) { $body .= '<option value="' . $edition->id . '"'; if ($args['edition'] == $edition->id) { $body .= ' select="selected"'; } $body .= '>' . $edition->name; if ($edition->current === '1') { $body .= ' [current]'; } $boduy .= '</option>'; } $body .= '</select> </div>'; } else { $body .= '<div class="suboption"> You don’t have any editions yet, you’ll need to create a new one. </div>'; } $body .= '</div> <div class="option"> <input type="checkbox" class="checkbox" name="make_current" id="make_current" value="1"'; if (!$editions) { $body .= 'checked="checked"'; } $body .= ' /> <label for="make_current">Make this edition current.</label> </div> <input type="submit" value="Import" /> </form> <form method="post" action="/admin/?page=parse&noframe=1"> <h3>Empty the Database</h3> <p> Remove data from the database. This leaves database tables intact. You may choose all data, or just data from a specific edition below. </p>'; if ($editions !== FALSE) { $body .= '<div class="suboption"> <select name="edition" value="edition"> <option value="">All Data</option>'; foreach ($editions as $edition) { $body .= '<option value="' . $edition->id . '"'; if ($args['edition'] == $edition->id) { $body .= ' select="selected"'; } $body .= '>' . $edition->name; if ($edition->current === '1') { $body .= ' [current]'; } $boduy .= '</option>'; } $body .= '</select> </div>'; } $body .= '<input type="hidden" name="action" value="empty" /> <input type="submit" value="Empty the Database" /> </form> <form method="post" action="/admin/?page=parse&noframe=1"> <h3>Rebuild Permalinks</h3> <p>Completely rebuild all permalinks for all editions of code.</p> <input type="hidden" name="action" value="permalinks" /> <input type="submit" value="Rebuild Permalinks" /> </form> <form method="post" action="/admin/?page=parse&noframe=1"> <h3>Test Your Environment</h3> <p>Verifies that the State Decoded will run on the current server environment.</p> <input type="hidden" name="action" value="test_environment" /> <input type="submit" value="Test Environment" /> </form>'; /* * If Memcached / Redis is in use, provide an option to clear the cache. */ global $cache; if (isset($cache)) { $body .= ' <form method="post" action="/admin/?page=parse&noframe=1"> <h3>Clear the In-Memory Cache</h3> <p>Delete all data currently stored in Memcached or Redis.</p> <input type="hidden" name="action" value="cache" /> <input type="submit" value="Clear Cache" /> </form>'; } return $body; }
public function index_laws($args) { if (!isset($this->edition)) { $edition_obj = new Edition(array('db' => $this->db)); $this->edition = $edition_obj->current(); } if (!isset($this->edition)) { throw new Exception('No edition, cannot index laws.'); } if ($this->edition->current != '1') { $this->logger->message('The edition is not current, skipping the update of the search ' . ' index', 9); return; } if (!defined('SEARCH_CONFIG')) { $this->logger->message('Solr is not in use, skipping index', 9); return; } else { /* * Index the laws. */ $this->logger->message('Updating search index', 5); $this->logger->message('Indexing laws', 6); $search_index = new SearchIndex(array('config' => json_decode(SEARCH_CONFIG, TRUE))); $law_obj = new Law(array('db' => $this->db)); $result = $law_obj->get_all_laws($this->edition->id, true); $search_index->start_update(); while ($law = $result->fetch()) { // Get the full data of the actual law. $document = new Law(array('db' => $this->db)); $document->law_id = $law['id']; $document->config->get_all = TRUE; $document->get_law(); // Bring over our edition info. $document->edition = $this->edition; try { $search_index->add_document($document); } catch (Exception $error) { $this->logger->message('Search index error "' . $error->getStatusMessage() . '"', 10); return FALSE; } } $search_index->commit(); // $this->logger->message('Indexing structures', 6); ### TODO: Index structures $this->logger->message('Laws were indexed', 5); return TRUE; } }
public function get_url($law_id, $edition_id = null, $permalink = false) { /* * If a section number hasn't been passed to this function, then there's nothing to do. */ if (empty($law_id)) { return FALSE; } /* * Set the default edition. */ if (empty($edition_id)) { $edition_obj = new Edition(array('db' => $this->db)); $edition = $edition_obj->current(); $edition_id = $edition->id; } $sql = 'SELECT * FROM permalinks WHERE object_type="law" AND relational_id = :law_id'; $sql_args = array(':law_id' => $law_id); if ($permalink === true) { $sql .= ' AND permalink = 1'; } else { $sql .= ' AND preferred = 1'; } $statement = $this->db->prepare($sql); $result = $statement->execute($sql_args); if ($result === FALSE || $statement->rowCount() == 0) { return FALSE; } $permalink = $statement->fetch(PDO::FETCH_OBJ); return $permalink; }
function handle($args) { /* * If we have received neither a term nor a section, we can't do anything. */ if (empty($args['term']) && empty($_GET['section'])) { json_error('Neither a dictionary term nor a section number have been provided.'); die; } /* * Clean up the term. */ $term = filter_var($args['term'], FILTER_SANITIZE_STRING); /* * If a section has been specified, then clean that up. */ if (isset($_GET['section'])) { $section = filter_input(INPUT_GET, 'section', FILTER_SANITIZE_STRING); } if (isset($_GET['law_id'])) { $law_id = filter_input(INPUT_GET, 'law_id', FILTER_SANITIZE_STRING); } if (isset($_GET['edition_id'])) { $edition_id = filter_input(INPUT_GET, 'edition_id', FILTER_SANITIZE_STRING); } else { $edition = new Edition(); $current_edition = $edition->current(); $edition_id = $current_edition->id; } $dict = new Dictionary(); /* * Get the definitions for the requested term, if a term has been requested. */ if (!empty($args['term'])) { if (isset($section)) { $dict->section_number = $section; } if (isset($law_id)) { $dict->law_id = $law_id; } if (isset($edition_id)) { $dict->edition_id = $edition_id; } $dict->term = $term; $dictionary = $dict->define_term(); /* * If, for whatever reason, this term is not found, return an error. */ if ($dictionary === FALSE) { $response = array('definition' => 'Definition not available.'); } else { /* * Uppercase the first letter of the first (quoted) word. We perform this twice because * some egal codes begin the definition with a quotation mark and some do not. (That is, * some write '"Whale" is a large sea-going mammal' and some write 'Whale is a large * sea-going mammal.") */ if (preg_match('/[A-Za-z]/', $dictionary->definition[0]) === 1) { $dictionary->definition[0] = strtoupper($dictionary->definition[0]); } elseif (preg_match('/[A-Za-z]/', $dictionary->definition[1]) === 1) { $dictionary->definition[1] = strtoupper($dictionary->definition[1]); } /* * If the request contains a specific list of fields to be returned. */ if (isset($_GET['fields'])) { /* * Turn that list into an array. */ $returned_fields = explode(',', urldecode($_GET['fields'])); foreach ($returned_fields as &$field) { $field = trim($field); } /* * It's essential to unset $field at the conclusion of the prior loop. */ unset($field); foreach ($dictionary as &$term) { /* * Step through our response fields and eliminate those that aren't in the * requested list. */ foreach ($term as $field => &$value) { if (in_array($field, $returned_fields) === FALSE) { unset($term->{$field}); } } } } /* * If a section has been specified, then simplify this response by returning just a * single definition. */ if (isset($section) || isset($law_id)) { $dictionary = $dictionary->{0}; } /* * Rename this variable to use the expected name. */ $response = $dictionary; } // end else if term is found } elseif (!empty($_GET['section'])) { /* * Get the structural ID of the container for this section. */ $law = new Law(); $law->section_number = $section; $law->config = FALSE; $result = $law->get_law(); if ($result == FALSE) { $response = array('terms' => 'Term list not available.'); } else { /* * Now get the term list. */ $dict->section_id = $law->section_id; $dict->structure_id = $law->structure_id; $response = $dict->term_list(); if ($response == FALSE) { $response = array('terms' => 'Term list not available.'); } } } // end elseif (!empty($args['section'])) $this->render($response, 'OK', $_REQUEST['callback']); }
$page = 1; } /* * If the number of results to display per page has been specified, include that. Otherwise, * the default is 10. */ if (!empty($_GET['num'])) { $per_page = filter_input(INPUT_GET, 'num', FILTER_SANITIZE_STRING); } else { $per_page = 10; } /* * Filter by edition. */ $edition_id = ''; $edition = new Edition(); if (!empty($_GET['edition_id'])) { $edition_id = filter_input(INPUT_GET, 'edition_id', FILTER_SANITIZE_STRING); } $content->set('current_edition', $edition_id); /* * Display our search form. */ $search->query = $q; $body .= $search->display_form($edition_id); /* * Execute the query. */ try { $results = $client->search(array('q' => decode_entities($q), 'edition_id' => $edition_id, 'page' => $page, 'per_page' => $per_page)); } catch (Exception $error) {