[ Index ]

PHP Cross Reference of YOURLS

title

Body

[close]

/includes/Database/ -> Options.php (source)

   1  <?php
   2  
   3  /**
   4   * YOURLS Options
   5   *
   6   * Note to plugin authors: you most likely SHOULD NOT use directly methods and properties of this class. Use instead
   7   * function wrappers (eg don't use $ydb->option, or $ydb->get(), use yourls_*_options() functions instead).
   8   *
   9   * Note to devs: this class internally uses function wrappers eg yourls_*_options() instead of direct methods, to
  10   * comply to any filter set in the function wrappers (eg $this->update() uses yourls_get_option()).
  11   * Maybe in the future this will look as a dumb idea?
  12   * The alternative would be to move return filters from function wrappers to here, but I think this will make things
  13   * less readable for users.
  14   *
  15   * @since 1.7.3
  16   */
  17  
  18  namespace YOURLS\Database;
  19  
  20  use YOURLS\Database\YDB;
  21  use PDOException;
  22  
  23  class Options {
  24  
  25      /**
  26       * Hold a copy of the all mighty $ydb global
  27       *
  28       * @var \YOURLS\Database\YDB
  29       */
  30      protected $ydb;
  31  
  32      public function __construct(YDB $ydb) {
  33          $this->ydb = $ydb;
  34      }
  35  
  36      /**
  37       * Read all options from DB at once, return bool
  38       *
  39       * @since  1.7.3
  40       * @see yourls_get_all_options()
  41       * @return bool    True on success, false on failure (eg table missing or empty)
  42       */
  43      public function get_all_options() {
  44          // Get option values from DB
  45          $table = YOURLS_DB_TABLE_OPTIONS;
  46          $sql = "SELECT option_name, option_value FROM $table WHERE 1=1";
  47  
  48          try {
  49              $options = (array) $this->ydb->fetchPairs($sql);
  50  
  51          } catch ( PDOException $e ) {
  52  
  53              // We could not fetch value from the table. Let's check if the option table exists
  54              try {
  55                  $check = $this->ydb->fetchAffected(sprintf("SHOW TABLES LIKE '%s'", $table));
  56                  // Table doesn't exist
  57                  if ($check ==0) {
  58                      return false;
  59                  }
  60  
  61              // Error at this point means the database isn't readable
  62              } catch ( PDOException $e ) {
  63                  $this->ydb->dead_or_error($e);
  64              }
  65  
  66          }
  67  
  68  
  69          // Unlikely scenario, but who knows: table exists, but is empty
  70          if (empty($options)) {
  71              return false;
  72          }
  73  
  74          foreach ($options as $name => $value) {
  75              $this->ydb->set_option($name, yourls_maybe_unserialize($value));
  76          }
  77  
  78          yourls_apply_filter('get_all_options', 'deprecated');
  79  
  80          return true;
  81      }
  82  
  83      /**
  84       * Get option value from DB (or from cache if available). Return value or $default if not found
  85       *
  86       * @since  1.7.3
  87       * @see yourls_get_option()
  88       * @param  string $name     Option name
  89       * @param  string $default  Value to return if option doesn't exist
  90       * @return mixed            Value set for the option
  91       */
  92      public function get($name, $default) {
  93          $name = trim((string)$name);
  94          if (empty($name)) {
  95              return $default;
  96          }
  97  
  98          // Check if option value is cached already
  99          if($this->ydb->has_option($name)) {
 100              return $this->ydb->get_option($name);
 101          }
 102  
 103          // Get option value from DB
 104          $table = YOURLS_DB_TABLE_OPTIONS;
 105          $sql = "SELECT option_value FROM $table WHERE option_name = :option_name LIMIT 1";
 106          $bind = array('option_name' => $name);
 107  
 108          // Use fechOne() to get array('option_value'=>$value), or false if not found.
 109          // This way, we can effectively store false as an option value, and not confuse with false as the default return value
 110          $value = $this->ydb->fetchOne($sql, $bind);
 111          if($value !== false) {
 112              $value = yourls_maybe_unserialize( $value['option_value'] );
 113              // Cache option value to save a DB query if needed later
 114              $this->ydb->set_option($name, $value);
 115          } else {
 116              $value = $default;
 117          }
 118  
 119          /**
 120           * We don't cache value if option is not set, to make a difference between "not found: returning false"
 121           * and "found, and value is false".
 122           * This way, we can:
 123           * $check = yourls_get_option('doesnt_exist'); // false
 124           * yourls_add_option('doesnt_exist', 'value'); // will work, because check on has_option() will return false
 125           */
 126  
 127          return $value;
 128      }
 129  
 130      /**
 131       * Update (add if doesn't exist) an option to DB
 132       *
 133       * @since  1.7.3
 134       * @see yourls_update_option()
 135       * @param  string $name      Option name. Expected to not be SQL-escaped.
 136       * @param  mixed  $newvalue  Option value.
 137       * @return bool              False if value was not updated, true otherwise.
 138       */
 139      public function update($name, $newvalue) {
 140          $name = trim((string)$name);
 141          if (empty($name)) {
 142              return false;
 143          }
 144  
 145          // Use clone to break object refs -- see commit 09b989d375bac65e692277f61a84fede2fb04ae3
 146          if (is_object($newvalue)) {
 147              $newvalue = clone $newvalue;
 148          }
 149  
 150          $oldvalue = yourls_get_option($name);
 151  
 152          // If the new and old values are the same, no need to update.
 153          if ($newvalue === $oldvalue) {
 154              return false;
 155          }
 156  
 157          // If this is a new option, just add it
 158          if (false === $oldvalue) {
 159              return $this->add($name, $newvalue);
 160          }
 161  
 162          $_newvalue = yourls_maybe_serialize($newvalue);
 163          $table = YOURLS_DB_TABLE_OPTIONS;
 164          $sql  = "UPDATE $table SET option_value = :value WHERE option_name = :name";
 165          $bind = array('name' => $name, 'value' => $_newvalue);
 166          $do   = $this->ydb->fetchAffected($sql, $bind);
 167  
 168          if($do !== 1) {
 169              // Something went wrong :(
 170              return false;
 171          }
 172  
 173          // Cache option value to save a DB query if needed later
 174          $this->ydb->set_option($name, $newvalue);
 175          yourls_do_action( 'update_option', $name, $oldvalue, $newvalue );
 176          return true;
 177      }
 178  
 179      /**
 180       * Add an option to the DB
 181       *
 182       * @since  1.7.3
 183       * @see yourls_add_option()
 184       * @param  string $name   Name of option to add. Expected to not be SQL-escaped.
 185       * @param  mixed  $value  Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped.
 186       * @return bool           False if option was not added (eg already exists), true otherwise.
 187       */
 188      public function add($name, $value) {
 189          $name = trim((string)$name);
 190          if (empty($name)) {
 191              return false;
 192          }
 193  
 194          // Use clone to break object refs -- see commit 09b989d375bac65e692277f61a84fede2fb04ae3
 195          if (is_object($value)) {
 196              $value = clone $value;
 197          }
 198  
 199          // Make sure the option doesn't already exist
 200          if ($this->ydb->has_option($name)) {
 201              return false;
 202          }
 203          // if (false !== yourls_get_option($name)) {
 204              // return false;
 205          // }
 206  
 207          $table = YOURLS_DB_TABLE_OPTIONS;
 208          $_value = yourls_maybe_serialize($value);
 209          $sql  = "INSERT INTO $table (option_name, option_value) VALUES (:name, :value)";
 210          $bind = array('name' => $name, 'value' => $_value);
 211          $do   = $this->ydb->fetchAffected($sql, $bind);
 212  
 213          if($do !== 1) {
 214              // Something went wrong :(
 215              return false;
 216          }
 217  
 218          // Cache option value to save a DB query if needed later
 219          $this->ydb->set_option($name, $value);
 220          yourls_do_action('add_option', $name, $_value);
 221  
 222          return true;
 223      }
 224  
 225      /**
 226       * Delete option from DB
 227       *
 228       * @since  1.7.3
 229       * @see yourls_delete_option()
 230       * @param  string $name  Option name to delete. Expected to not be SQL-escaped.
 231       * @return bool          False if option was not deleted (eg not found), true otherwise.
 232       */
 233      public function delete($name) {
 234          $name = trim((string)$name);
 235          if (empty($name)) {
 236              return false;
 237          }
 238  
 239          $table = YOURLS_DB_TABLE_OPTIONS;
 240          $sql = "DELETE FROM $table WHERE option_name = :name";
 241          $bind = array('name' => $name);
 242          $do   = $this->ydb->fetchAffected($sql, $bind);
 243  
 244          if($do !== 1) {
 245              // Something went wrong :(
 246              return false;
 247          }
 248  
 249          yourls_do_action('delete_option', $name);
 250          $this->ydb->delete_option($name);
 251          return true;
 252      }
 253  
 254  }


Generated: Tue Sep 27 05:10:01 2022 Cross-referenced by PHPXref 0.7.1