This commit is contained in:
2026-04-26 23:47:49 +02:00
parent 1b95f03d1e
commit b073e009d8
5288 changed files with 1112699 additions and 55536 deletions

View File

@@ -0,0 +1,385 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
abstract class Api {
public $Helper;
public $Cache;
public $Throttle;
public $User;
public $Debug;
public $Url;
public $pluginSlug;
public $pluginFile;
public $debugMode;
public $startTime;
private $proxy;
private $routes;
public static $client;
public static $ERROR_UNKNOWN;
public static $ERROR_INVALID_REQUEST;
public static $ERROR_INVALID_ROUTE;
public static $ERROR_INVALID_AUTH;
public static $ERROR_CURL;
public function __construct($config, $routes) {
self::$ERROR_UNKNOWN = __('Service is unavailable now');
self::$ERROR_INVALID_REQUEST = __('invalid request');
self::$ERROR_INVALID_AUTH = __('Invalid auth');
self::$ERROR_INVALID_ROUTE = __('Requested route not found');
self::$ERROR_CURL = __('The plugin cant make a request. The reason is that cURL PHP Library is not available or requested domain is blocked on your server. To fix this please contact your hosting or server administrator.');
$this->pluginSlug = $config['plugin_slug'];
$this->pluginFile = $config['plugin_file'];
$this->debugMode = isset($config['debug_mode']) ? $config['debug_mode'] : false;
$this->startTime = round(microtime(true) * 1000);
$this->proxy = $this->setProxy($config);
$this->routes = $routes;
// @TODO static Helper
$this->Helper = new Helper($this->pluginSlug);
$this->Cache = new Cache($this->Helper, $config);
$this->Url = new Url();
$this->initOptions($config);
$this->Debug = $this->initDebug($this->debugMode);
if (isset($config['use']) && in_array('throttle', $config['use'])) {
$this->Throttle = new Throttle($this->Helper, $config);
}
if (isset($config['use']) && in_array('user', $config['use'])) {
$this->User = new User($this->Helper, $config);
}
add_action('rest_api_init', array($this, 'registerRoutes'));
add_action('rest_api_init', array($this, 'permalinkRestRouteFix'));
// add_action('rest_api_init', function() {
// header('Access-Control-Allow-Origin: *');
// });
}
public function permalinkRestRouteFix() {
global $wp;
if (isset($wp->query_vars['rest_route']) && strpos($wp->query_vars['rest_route'], $this->pluginSlug . '/api') !== false) {
$split = explode('?q=', $wp->query_vars['rest_route']);
if (count($split) === 2) {
$wp->query_vars['rest_route'] = $split[0];
$_REQUEST['q'] = $split[1];
}
}
}
public function registerRoutes() {
register_rest_route($this->pluginSlug, '/api/', array(
'methods' => 'GET, POST',
'callback' => array($this, 'run'),
'permission_callback' => '__return_true'
));
register_rest_route($this->pluginSlug, '/api/(?P<endpoint>[\w-]+)', array(
'methods' => 'GET, POST',
'callback' => array($this, 'run'),
'permission_callback' => '__return_true',
'args' => array(
'endpoint' => array(
'required' => false,
'default' => '',
'enum' => array_keys($this->routes)
)
)
));
}
public function initDebug($debug_mode) {
if (class_exists('\ElfsightYoutubeGalleryApi\Debug')) {
return new \ElfsightYoutubeGalleryApi\Debug($this, $debug_mode);
} else {
return new \ElfsightYoutubeGalleryApi\Core\Debug($this, $debug_mode);
}
}
public function initOptions($config) {
if (class_exists('\ElfsightYoutubeGalleryApi\Options')) {
return new \ElfsightYoutubeGalleryApi\Options($this->Helper, $config);
} else {
return new \ElfsightYoutubeGalleryApi\Core\Options($this->Helper, $config);
}
}
public function run(\WP_REST_Request $request) {
$endpoint = $request->get_param('endpoint');
$route = isset($this->routes[$endpoint]) ? $this->routes[$endpoint] : null;
if (empty($route) || !method_exists($this, $route)) {
$this->error(400, self::$ERROR_INVALID_REQUEST, self::$ERROR_INVALID_ROUTE);
}
return call_user_func(array($this, $route));
}
public function request($type, $url, $options = array()) {
$type = strtoupper($type);
$curl = curl_init();
$request_url = $url;
if (!empty($options['query'])) {
$request_url .= '?' . http_build_query($options['query']);
}
$curl_options = array(
CURLOPT_URL => $request_url,
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CONNECTTIMEOUT => 60,
CURLOPT_TIMEOUT => 60,
CURLOPT_FOLLOWLOCATION => !empty($options['follow']) && $options['follow'],
CURLOPT_HTTPHEADER => $this->getHeadersList($options),
CURLOPT_PROXY => $this->proxy['url'],
CURLOPT_PROXYUSERPWD => $this->proxy['credentials']
);
curl_setopt_array($curl, $curl_options);
$response = curl_exec($curl);
$info = curl_getinfo($curl);
$error = curl_error($curl);
curl_close($curl);
if (isset($options['debug']) && $options['debug']) {
return [$response, $info, $error];
}
if ($info['http_code'] === 0) {
$this->error(400, self::$ERROR_CURL, $error);
}
return $this->formatResponse($response);
}
private function getHeadersList($options = array()) {
$headers_raw_list = array();
$cookies_raw_list = array();
$cookies = !empty(self::$client['cookies']) ? self::$client['cookies'] : array();
$headers = !empty(self::$client['headers']) ? self::$client['headers'] : array();
if (!empty($options['cookies'])) {
$cookies = $this->Helper->arrayMergeAssoc($cookies, $options['cookies']);
}
if (isset($options['headers'])) {
$headers = $this->Helper->arrayMergeAssoc($headers, $options['headers']);
}
foreach ($cookies as $cookie_name => $cookie_value) {
$cookies_raw_list[] = $cookie_name . '=' . $cookie_value;
}
unset($cookie_name, $cookie_data);
$headers['Cookie'] = implode('; ', $cookies_raw_list);
foreach ($headers as $header_key => $header_value) {
$headers_raw_list[] = $header_key . ': ' . $header_value;
}
unset($header_key, $header_value);
return $headers_raw_list;
}
public function formatResponse($response) {
@list ($response_headers_str, $response_body_encoded, $alt_body_encoded) = explode("\r\n\r\n", $response);
if ($alt_body_encoded) {
$response_headers_str = $response_body_encoded;
$response_body_encoded = $alt_body_encoded;
}
$response_body = $response_body_encoded;
$response_headers_raw_list = explode("\r\n", $response_headers_str);
$response_http = array_shift($response_headers_raw_list);
preg_match('#^([^\s]+)\s(\d+)\s?([^$]+)?$#', $response_http, $response_http_matches);
array_shift($response_http_matches);
list ($response_http_protocol, $response_http_code) = $response_http_matches;
$response_http_message = '';
if (isset($response_http_matches[2])) {
$response_http_message = $response_http_matches[2];
}
$response_headers = array();
$response_cookies = array();
foreach ($response_headers_raw_list as $header_row) {
list ($header_key, $header_value) = explode(': ', $header_row, 2);
if (strtolower($header_key) === 'set-cookie') {
$cookie_params = explode('; ', $header_value);
if (empty($cookie_params[0])) {
continue;
}
list ($cookie_name, $cookie_value) = explode('=', $cookie_params[0]);
$response_cookies[$cookie_name] = $cookie_value;
} else {
$response_headers[$header_key] = $header_value;
}
}
unset($header_row, $header_key, $header_value, $cookie_name, $cookie_value);
if ($response_cookies) {
self::$client['cookies'] = $this->Helper->arrayMergeAssoc(self::$client['cookies'] ?: array(), $response_cookies);
}
return array(
'status' => 1,
'http_protocol' => $response_http_protocol,
'http_code' => (int) $response_http_code,
'http_message' => $response_http_message,
'headers' => $response_headers,
'cookies' => $response_cookies,
'body' => $response_body
);
}
public function response($data, $options = array()) {
if (ob_get_length()) {
ob_end_clean();
ob_start();
}
$default_options = array(
'encode' => false,
'plain' => false
);
$options = !empty($options) ? array_merge($default_options, $options) : $default_options;
$callback = $this->input('callback', null, false);
$output = $options['encode'] ? json_encode($data) : $data;
$content_type = $options['plain'] ? 'text/html' : 'application/json';
if (!empty($callback)) {
$callback = htmlspecialchars(strip_tags($callback));
$validate_callback = preg_match('#^jQuery[0-9]*\_[0-9]*$#', $callback);
if ($validate_callback) {
$output = '/**/ ' . $callback . '(' . $output . ')';
$content_type = 'application/javascript';
}
}
header('Content-type: ' . $content_type . '; charset=utf-8');
exit($output);
}
public function error($code = 400, $error_message = null, $additional = '') {
if (!$error_message) {
$error_message = self::$ERROR_UNKNOWN;
}
$error = array(
'meta' => array(
'code' => $code,
'error_message' => $error_message
)
);
if ($additional) {
$additional && $error['meta']['_additional'] = $additional;
}
$this->response($error, array('encode' => true));
}
public function subError($additional) {
return $this->error(400, self::$ERROR_UNKNOWN, $additional);
}
public function input($name, $default = null, $check_empty = true) {
$query = array();
if (empty($_REQUEST)) {
$parsed_url = parse_url($_SERVER['REQUEST_URI']);
if (isset($parsed_url['query'])) {
parse_str($parsed_url['query'], $query);
}
} else {
$query = $_REQUEST;
}
$value = isset($query[$name]) ? $query[$name] : $default;
if (empty($value) && $check_empty) {
$this->error(400, self::$ERROR_INVALID_REQUEST, $name . ' is not defined');
}
return is_string($value) ? urldecode($value) : $value;
}
private function setProxy($config) {
$url = null;
$credentials = null;
if (isset($config['proxy'])) {
$proxy_config = $config['proxy'];
if (isset($proxy_config['proxy']) && !empty($proxy_config['proxy'])) {
if (!empty($proxy_config['proxy']['server'])) {
$url = $proxy_config['proxy']['server'];
}
if (!empty($proxy_config['proxy']['user']) && !empty($proxy_config['proxy']['password'])) {
$credentials = $proxy_config['proxy']['user'] . ':' . $proxy_config['proxy']['password'];
}
}
}
return array(
'url' => $url,
'credentials' => $credentials
);
}
public function checkResponse($response, $checkCode = true) {
$hasResponse = !empty($response) && !empty($response['body']) && !empty($response['http_code']);
if (!$hasResponse) {
return false;
}
if ($checkCode && (int) $response['http_code'] !== 200) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class Cache {
private $Helper;
private $pluginFile;
private $cacheTime;
private $tableName;
public function __construct($Helper, $config) {
$this->Helper = $Helper;
$this->pluginFile = $config['plugin_file'];
$this->cacheTime = !empty($config['cache_time']) ? $config['cache_time'] : 43200;
$clear_cache = isset($config['clear_cache_on_update']) ? $config['clear_cache_on_update'] : true;
$this->tableName = $this->Helper->getTableName('cache');
if (!$this->Helper->tableExist($this->tableName)) {
$this->Helper->tableCreate($this->tableName, array('key' => 'text', 'data' => 'longtext'));
}
if ($clear_cache) {
register_deactivation_hook($this->pluginFile, array($this, 'dropTable'));
}
}
public function keyFromQuery($query, $excluded_params = array('access_token')) {
$key = $query;
foreach ($excluded_params as $param) {
$key = $this->Helper->removeQueryParam($key, $param);
}
return preg_replace('#\?$#', '', $key);
}
public function get($key, $check_expire = true) {
$cache = $this->Helper->tableRowGet($this->tableName, array('key' => $key));
if (!$cache || ($check_expire && time() > $cache['updated_at'] + $this->cacheTime)) {
return null;
}
return $cache['data'];
}
public function expired($key) {
$cache = $this->Helper->tableRowGet($this->tableName, array('key' => $key));
return !$cache || $cache && time() > $cache['updated_at'] + $this->cacheTime;
}
public function set($key, $data, $merge = false) {
if (empty($data)) {
return false;
}
$data = $merge ? $this->merge($data, $this->get($key, false)) : $data;
$data = is_array($data) ? json_encode($data) : $data;
return !!$this->Helper->tableRowUpdate(
$this->tableName,
array(
'key' => $key,
'data' => $data
),
array('key' => $key)
);
}
private function merge($data, $cache_data_json){
if (empty($cache_data_json) || empty($data)) {
return $data;
} else {
$cache_data = json_decode($cache_data_json, true);
$unique_data = $this->Helper->uniqueSort(array_merge_recursive($data, $cache_data), 'created_time');
return $unique_data; // @TODO slice by limit
}
}
public function dropTable() {
global $wpdb;
return $wpdb->query("DROP TABLE IF EXISTS $this->tableName");
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class Debug {
public $Api;
public $Helper;
public $debugMode;
static $pass = '8JwSgpRpB4cDhY2q';
public function __construct($Api, $debug_mode = false) {
$this->Api = $Api;
$this->Helper = $Api->Helper;
$this->debugMode = $debug_mode;
add_action('rest_api_init', array($this, 'registerRoutes'));
}
public function registerRoutes() {
register_rest_route($this->Api->pluginSlug, '/api/debug/(?P<endpoint>[\w-]+)', array(
'methods' => 'GET',
'callback' => array($this, 'run'),
'permission_callback' => '__return_true',
'args' => array(
'endpoint' => array(
'required' => true
)
)
));
}
public function run(\WP_REST_Request $request) {
$params = $request->get_params();
$endpoint = $params['endpoint'];
if (empty($endpoint) || !method_exists($this, $endpoint)) {
$this->Api->error(400, 'invalid request', 'requested route not found');
}
return call_user_func(array($this, $endpoint), $params);
}
private function restrict($params) {
if (!isset($params['pass']) || $params['pass'] !== self::$pass) {
$this->Api->error(400, 'restricted');
}
}
public function request($params) {
$test_url = isset($params['test_url']) ? $params['test_url'] : 'https://www.google.com';
$test_request = $this->Api->request('get', $test_url, array('debug' => true));
list($curl_response, $curl_info, $curl_error) = $test_request;
$data = array(
'info' => $curl_info,
'error' => $curl_error
);
if (isset($params['with_response']) && $params['with_response'] === 'true') {
$data['response'] = $curl_response;
}
$this->Api->response(array(
'status' => $curl_info['http_code'],
'test_url' => $test_url,
'request_data' => $data
), array('encode' => true));
}
public function php($params) {
$this->restrict($params);
$avail_what = array(4,8);
$what = isset($params['what']) && in_array($params['what'], $avail_what) ? $params['what'] : 4;
header('Content-type: text/html; charset=UTF-8');
phpinfo($what);
exit();
}
public function dump($data, $die = false)
{
$this->dd($data, $die);
}
public function dd($data, $die = true)
{
if (!$this->debugMode) {
return;
}
header('Content-type: text/html; charset=UTF-8');
echo '<pre>';
print_r($data);
echo '</pre>';
$die && die();
}
}

View File

@@ -0,0 +1,163 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class Helper {
public $pluginSlug;
public function __construct($pluginSlug) {
$this->pluginSlug = $pluginSlug;
}
public function getOptionName($name, $delimiter = '_') {
return str_replace('-', $delimiter, $this->pluginSlug) . ($name ? $delimiter . $name : '');
}
public function getPluginSlug() {
return $this->pluginSlug;
}
public function getTableName($name) {
global $wpdb;
return esc_sql($wpdb->prefix . $this->getOptionName($name));
}
public function tableExist($table_name) {
global $wpdb;
return !!$wpdb->get_var($wpdb->prepare(
"SHOW TABLES LIKE %s",
$table_name
));
}
public function tableCreate($table_name, $columns) {
global $wpdb;
$columns['updated_at'] = 'int(12)';
$columns_query = '';
foreach ($columns as $key => $type) {
$columns_query .= '`' . $key . '` ' . $type . ' NOT NULL,';
}
return $wpdb->query(
"CREATE TABLE $table_name (`id` int(11) unsigned NOT NULL AUTO_INCREMENT, $columns_query PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;"
);
}
public function tableRowGet($table_name, $where) {
global $wpdb;
list ($key, $value) = $this->getKeyValue($where);
return $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name WHERE `$key` = %s",
esc_sql($value)
), ARRAY_A);
}
public function tableRowExist($table_name, $where) {
global $wpdb;
list ($key, $value) = $this->getKeyValue($where);
return !!$wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table_name WHERE `$key` = %s",
esc_sql($value)
));
}
public function getKeyValue($array) {
$keys = array_keys($array);
$values = array_values($array);
return array($keys[0], $values[0]);
}
public function tableRowUpdate($table_name, $data, $where) {
global $wpdb;
$data['updated_at'] = time();
if ($this->tableRowExist($table_name, $where)) {
$status = $wpdb->update(
$table_name,
$data,
$where
);
} else {
$status = $wpdb->insert(
$table_name,
$data
);
}
return !!$status;
}
public function addQueryParam($url, $key, $val) {
return $url . (strpos($url,'?') !== false ? '&' : '?') . $key . '=' . $val;
}
public function removeQueryParam($url, $key) {
$result = $url;
$url_data = parse_url($url);
if (!empty($url_data['query'])) {
parse_str($url_data['query'], $query_params);
if (!empty($query_params[$key])) {
unset($query_params[$key]);
}
$result = $url_data['path'] . '?' . http_build_query($query_params);
}
return $result;
}
public function uniqueSort($array, $key) {
$result = array();
$array_unique = array();
$ids = array();
$timestamps = array();
foreach ($array as $item) {
if (!in_array($item['id'], $ids)) {
$ids_unique[] = $item['id'];
$array_unique[$item['id']] = $item;
$timestamps[$item['id']] = $item[$key];
}
}
arsort($timestamps);
foreach ($timestamps as $id => $node) {
$result[] = $array_unique[$id];
}
return $result;
}
public function arrayMergeAssoc() {
$mixed = null;
$arrays = func_get_args();
foreach ($arrays as $k => $arr) {
if ($k === 0) {
$mixed = $arr;
continue;
}
$mixed = array_combine(
array_merge(array_keys($mixed), array_keys($arr)),
array_merge(array_values($mixed), array_values($arr))
);
}
return $mixed;
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class Options {
public $Helper;
public $apiUrl;
public $editorSettings;
public function __construct($Helper) {
$this->Helper = $Helper;
add_filter($this->Helper->getOptionName('shortcode_options'), array($this, 'shortcodeOptionsFilter'));
add_filter($this->Helper->getOptionName('widget_options'), array($this, 'widgetOptionsFilter'));
add_filter($this->Helper->getOptionName('editor_settings'), array($this, 'editorSettingsFilter'));
}
public function editorSettingsFilter($config) {
$this->editorSettings = $config;
$this->apiUrl = rest_url($this->Helper->getPluginSlug() . '/api');
$this->addOptions();
$this->modifyOptions();
$this->deleteOptions();
return $this->editorSettings;
}
public function addOptions() {
$this->addOption(array(
'id' => 'apiUrl',
'type' => 'hidden',
'defaultValue' => $this->apiUrl
));
}
public function modifyOptions() {
}
public function deleteOptions() {
}
public function addOption($data) {
if (!is_array($this->editorSettings)) {
return;
}
array_push($this->editorSettings['properties'], $data);
}
public function modifyOption($id, $data, &$properties = null) {
if (!isset($properties)) {
$properties = &$this->editorSettings['properties'];
}
if (!is_array($properties)) {
return;
}
foreach ($properties as &$property) {
if (!empty($property['id']) && $property['id'] === $id) {
$property = array_merge($property, $data);
}
if ($property['type'] === 'subgroup') {
$this->modifyOption($id, $data, $property['subgroup']['properties']);
}
}
}
public function deleteOption($id, &$properties = null) {
if (!isset($properties)) {
$properties = &$this->editorSettings['properties'];
}
foreach ($properties as $i => &$property) {
if ($property['type'] === 'subgroup') {
$this->modifyOption($id, $property['subgroup']['properties']);
}
if (!empty($property['id']) && $property['id'] === $id) {
array_splice($properties, $i, 1);
return;
}
}
}
public function shortcodeOptionsFilter($options) {
$this->apiUrl = rest_url($this->Helper->getPluginSlug() . '/api');
if (is_array($options)) {
$options['apiUrl'] = $this->apiUrl;
}
return $options;
}
public function widgetOptionsFilter($options_json) {
$options = json_decode($options_json, true);
if (is_array($options)) {
unset($options['api']);
unset($options['apiUrl']);
}
return json_encode($options);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class Throttle {
private $Helper;
private $pluginFile;
private $tableName;
private $calls;
private $time;
public function __construct($Helper, $config) {
$this->Helper = $Helper;
$this->pluginFile = $config['plugin_file'];
$this->calls = $config['throttle']['calls'];
$this->time = $config['throttle']['time'];
$this->tableName = $this->Helper->getTableName('throttle');
if (!$this->Helper->tableExist($this->tableName)) {
$this->Helper->tableCreate($this->tableName, array('calls' => 'int(2)'));
}
register_deactivation_hook($this->pluginFile, array($this, 'dropTable'));
}
public function isLimited() {
$usage = $this->Helper->tableRowGet($this->tableName, array('id' => 1));
if ($usage && $usage['calls'] > $this->calls) {
if (time() < $usage['updated_at'] + $this->time) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public function increment() {
$usage = $this->Helper->tableRowGet($this->tableName, array('id' => 1));
$calls_cnt = $usage && $usage['calls'] ? $usage['calls'] + 1 : 1;
if ($usage && $usage['calls'] > $this->calls && time() > $usage['updated_at'] + $this->time) {
$calls_cnt = 0;
}
return !!$this->Helper->tableRowUpdate(
$this->tableName,
array('calls' => $calls_cnt),
array('id' => 1)
);
}
public function dropTable() {
global $wpdb;
return $wpdb->query("DROP TABLE IF EXISTS $this->tableName");
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class Url {
public static function buildUrl($path, $params = [])
{
return $path . (!empty($params) ? '?' . http_build_query($params) : '');
}
public static function addQueryParams($subject, $params = [])
{
list($url, $query_params) = self::parseUrl($subject);
foreach ($params as $key => $value) {
$query_params[$key] = $value;
}
return self::buildUrl($url, $query_params);
}
public static function parseUrl($subject)
{
$url_data = parse_url($subject);
$query_params = [];
if (!empty($url_data['query'])) {
parse_str($url_data['query'], $query_params);
}
$url = "{$url_data['scheme']}://{$url_data['host']}{$url_data['path']}";
return [$url, $query_params];
}
public function setRequestUrl($url, $baseUrl = '', $params = array()){
$requestUrl = $url;
if (stripos($requestUrl, $baseUrl) === false) {
$requestUrl = $baseUrl . preg_replace('/^\/+/', '', $requestUrl);
}
return self::addQueryParams($requestUrl, $params);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace ElfsightYoutubeGalleryApi\Core;
class User {
private $Helper;
private $pluginFile;
private $tableName;
public function __construct($Helper, $config) {
$this->Helper = $Helper;
$this->pluginFile = $config['plugin_file'];
$this->tableName = $this->Helper->getTableName('user');
if (!$this->Helper->tableExist($this->tableName)) {
$this->Helper->tableCreate($this->tableName, array('public_id' => 'varchar(255)', 'data' => 'text'));
}
}
public function get($public_id) {
return $this->Helper->tableRowGet($this->tableName, array('public_id' => $public_id));
}
public function set($public_id, $data) {
return !!$this->Helper->tableRowUpdate(
$this->tableName,
array(
'public_id' => $public_id,
'data' => $data
),
array('public_id' => $public_id)
);
}
}

View File

@@ -0,0 +1,5 @@
<?php
// Silence is golden ;)
?>