/**
  * @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());
 }
Пример #2
0
 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();
 }
Пример #3
0
 /**
  * @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());
 }
Пример #4
0
 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();
 }
Пример #5
0
 /**
  * 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;
 }
Пример #6
0
 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();
 }
Пример #7
0
 /**
  * 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();
 }