/** * @testdox A user who can only create records in one table can still use the change-tracker (i.e. creating changesets is not influenced by standard grants). * @test */ public function minimal_grants() { global $current_user; $current_user->remove_cap('promote_users'); $current_user->add_role('subscriber'); $grants = new Grants(); $grants->set(array('test_table' => array(Grants::READ => array('subscriber'), Grants::CREATE => array('subscriber')))); // Assert that the permissions are set as we want them. $this->assertTrue(Grants::current_user_can(Grants::CREATE, 'test_table')); $this->assertFalse(Grants::current_user_can(Grants::CREATE, ChangeTracker::changesets_name())); $this->assertFalse(Grants::current_user_can(Grants::CREATE, ChangeTracker::changes_name())); // Succcessfully save a record. $test_table = $this->db->get_table('test_table'); $rec = $test_table->save_record(array('title' => 'One', 'changeset_comment' => 'Testing.')); $this->assertEquals(1, $rec->id()); }
public function index($args) { // Get database and table. $db = new \WordPress\Tabulate\DB\Database($this->wpdb); $table = $db->get_table($args['table']); // Give it all to the template. $template = $this->get_template($table); if (isset($args['ident'])) { $template->record = $table->get_record($args['ident']); // Check permission. if (!Grants::current_user_can(Grants::UPDATE, $table->get_name())) { $template->add_notice('error', 'You do not have permission to update data in this table.'); } } if (!isset($template->record) || $template->record === false) { $template->record = $table->get_default_record(); // Check permission. if (!Grants::current_user_can(Grants::CREATE, $table->get_name())) { $template->add_notice('error', 'You do not have permission to create records in this table.'); } } // Don't save to non-updatable views. if (!$table->is_updatable()) { $template->add_notice('error', "This table can not be updated."); } return $template->render(); }
/** * @testdox Tables can be linked to each other; one is the referenced table, the other the referencing. * @test */ public function references() { // Make sure the user can edit things. global $current_user; $current_user->add_role('administrator'); $grants = new Grants(); $grants->set(array('test_table' => array(Grants::READ => array('administrator')))); // That test_table references test_types $test_table = $this->db->get_table('test_table'); $referenced_tables = $test_table->get_referenced_tables(true); $referenced_table = array_pop($referenced_tables); $this->assertEquals('test_types', $referenced_table->get_name()); // And the other way around. $type_table = $this->db->get_table('test_types'); $referencing_tables = $type_table->get_referencing_tables(); $referencing_table = array_pop($referencing_tables); $this->assertEquals('test_table', $referencing_table['table']->get_name()); }
protected function form_format(Table $table, $attrs) { if (!Grants::current_user_can(Grants::CREATE, $table)) { return 'You do not have permission to create ' . $table->get_title() . ' records.'; } $template = new Template('record/shortcode.html'); $template->table = $table; $template->record = $table->get_default_record(); $template->return_to = get_the_permalink(); return $template->render(); }
/** * Privide details of the relevant parts of the database schema, for use by * TabulateApp. */ public function app_schema() { $db = new Database($this->wpdb); $tables = $db->get_tables(); $out = array(); foreach ($tables as $table) { if (Grants::current_user_can(Grants::CREATE, $table->get_name())) { $out[] = $table->get_name(); } } return $out; }
public function index($args) { // Get database and table. $db = new \WordPress\Tabulate\DB\Database($this->wpdb); $table = $db->get_table($args['table']); // Give it all to the template. $template = $this->get_template($table); if (isset($args['ident'])) { $template->record = $table->get_record($args['ident']); // Check permission. if (!Grants::current_user_can(Grants::UPDATE, $table->get_name())) { $template->add_notice('error', 'You do not have permission to update data in this table.'); } } if (!isset($template->record) || $template->record === false) { $template->record = $table->get_default_record(); // Check permission. if (!Grants::current_user_can(Grants::CREATE, $table->get_name())) { $template->add_notice('error', 'You do not have permission to create records in this table.'); } // Add query-string values. if (isset($args['defaults'])) { $template->record->set_multiple($args['defaults']); } } // Don't save to non-updatable views. if (!$table->is_updatable()) { $template->add_notice('error', "This table can not be updated."); } // Enable postboxes (for the history and related tables' boxen). wp_enqueue_script('dashboard'); // Return to URL. if (isset($args['return_to'])) { $template->return_to = $args['return_to']; } return $template->render(); }
/** * This action is for importing a single CSV file into a single database table. * It guides the user through the four stages of importing: * uploading, field matching, previewing, and doing the actual import. * All of the actual work is done in [WebDB_File_CSV]. * * 1. In the first stage, a CSV file is **uploaded**, validated, and moved to a temporary directory. * The file is then accessed from this location in the subsequent stages of importing, * and only deleted upon either successful import or the user cancelling the process. * (The 'id' parameter of this action is the identifier for the uploaded file.) * 2. Once a valid CSV file has been uploaded, * its colums are presented to the user to be **matched** to those in the database table. * The columns from the database are presented first and the CSV columns are matched to these, * rather than vice versa, * because this way the user sees immediately what columns are available to be imported into. * 3. The column matches are then used to produce a **preview** of what will be added to and/or changed in the database. * All columns from the database are shown (regardless of whether they were in the import) and all rows of the import. * If a column is not present in the import the database will (obviously) use the default value if there is one; * this will be shown in the preview. * 4. When the user accepts the preview, the actual **import** of data is carried out. * Rows are saved to the database using the usual [WebDB_DBMS_Table::save()](api/Webdb_DBMS_Table#save_row), * and a message presented to the user to indicate successful completion. * * @return void */ public function import($args) { $template = new \WordPress\Tabulate\Template('import.html'); // Set up the progress bar. $template->stages = array('choose_file', 'match_fields', 'preview', 'complete_import'); $template->stage = 'choose_file'; // First make sure the user is allowed to import data into this table. $table = $this->get_table($args['table']); $template->record = $table->get_default_record(); $template->action = 'import'; $template->table = $table; $template->maxsize = size_format(wp_max_upload_size()); if (!Grants::current_user_can(Grants::IMPORT, $table->get_name())) { $template->add_notice('error', 'You do not have permission to import data into this table.'); return $template->render(); } /* * Stage 1 of 4: Uploading. */ $template->form_action = $table->get_url('import'); try { $hash = isset($_GET['hash']) ? $_GET['hash'] : false; $uploaded = isset($_FILES['file']) ? wp_handle_upload($_FILES['file']) : false; $csv_file = new \WordPress\Tabulate\CSV($hash, $uploaded); } catch (\Exception $e) { $template->add_notice('error', $e->getMessage()); return $template->render(); } /* * Stage 2 of 4: Matching fields */ if ($csv_file->loaded()) { $template->file = $csv_file; $template->stage = $template->stages[1]; $template->form_action .= "&hash=" . $csv_file->hash; } /* * Stage 3 of 4: Previewing */ if ($csv_file->loaded() and isset($_POST['preview'])) { $template->stage = $template->stages[2]; $template->columns = serialize($_POST['columns']); $errors = array(); // Make sure all required columns are selected foreach ($table->get_columns() as $col) { // Handle missing columns separately; other column errors are // done in the CSV class. Missing columns don't matter if importing // existing records. $missing = empty($_POST['columns'][$col->get_name()]); $pk_present = isset($_POST['columns'][$table->get_pk_column()->get_name()]); if (!$pk_present && $col->is_required() && $missing) { $errors[] = array('column_name' => '', 'column_number' => '', 'field_name' => $col->get_name(), 'row_number' => 'N/A', 'messages' => array('Column required, but not found in CSV')); } } $template->errors = empty($errors) ? $csv_file->match_fields($table, wp_unslash($_POST['columns'])) : $errors; } /* * Stage 4 of 4: Import */ if ($csv_file->loaded() and isset($_POST['import'])) { $template->stage = $template->stages[3]; $this->wpdb->query('BEGIN'); $result = $csv_file->import_data($table, unserialize(wp_unslash($_POST['columns']))); $this->wpdb->query('COMMIT'); $template->add_notice('updated', 'Import complete; ' . $result . ' rows imported.'); } return $template->render(); }