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;
 }
Example #2
0
/**
 * 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">';
Example #3
0
 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']);
        }
    }
Example #5
0
/**
 * 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.
     */
Example #6
0
/**
 * 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.
 */
Example #7
0
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">.&thinsp;.&thinsp;.</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 .&thinsp;.&thinsp;.</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']);
 }
Example #11
0
     $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) {