Initial commit
0 parents
Showing
4 changed files
with
314 additions
and
0 deletions
README.md
0 → 100644
| 1 | # BTFlags | ||
| 2 | Flag Manager for Baytech Sites. | ||
| 3 | |||
| 4 | ## Define Flag Directory in your constants.php file | ||
| 5 | |||
| 6 | ``` | ||
| 7 | define('DEFAULT_PPG', '14'); | ||
| 8 | ``` | ||
| 9 | |||
| 10 | ## Initialize Flag Manager | ||
| 11 | |||
| 12 | ``` | ||
| 13 | $flagManager = new \BTFlags\FlagManager(); | ||
| 14 | ``` | ||
| 15 | |||
| 16 | ### Data Structure | ||
| 17 | ``` | ||
| 18 | $requestData = array( | ||
| 19 | 'name' => null|string, | ||
| 20 | 'is_encrypyed' => true|false, | ||
| 21 | 'is_filtered' => true|false, | ||
| 22 | 'encrypted_name' => null|string, | ||
| 23 | 'has_default' => true|false, | ||
| 24 | 'default' => null|string, | ||
| 25 | 'accepted_values' => array( | ||
| 26 | 'value' => null|string, | ||
| 27 | 'encrypted_value' => null|string, | ||
| 28 | ), | ||
| 29 | ); | ||
| 30 | ``` | ||
| 31 | |||
| 32 | ## CRUD | ||
| 33 | ``` | ||
| 34 | // Create a Flag | ||
| 35 | $created = $flagManager->create($requestData); | ||
| 36 | |||
| 37 | // Delete a Flag | ||
| 38 | $deleted = $flagManager->delete($requestData); | ||
| 39 | |||
| 40 | // Update a Flag | ||
| 41 | $updated = $flagManager->update($requestData); | ||
| 42 | |||
| 43 | // Get all Flags | ||
| 44 | $flags = $flagManager->all(); | ||
| 45 | ``` | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
composer.json
0 → 100644
| 1 | { | ||
| 2 | "name": "btrepo/flags", | ||
| 3 | "description": "Flag Manager for Baytech Sites.", | ||
| 4 | "version": "1.0.3", | ||
| 5 | "type": "package", | ||
| 6 | "autoload": { | ||
| 7 | "psr-0": { | ||
| 8 | "BTFlags": "src/" | ||
| 9 | }, | ||
| 10 | "psr-4": { | ||
| 11 | "BTFlags\\": "src/" | ||
| 12 | } | ||
| 13 | }, | ||
| 14 | "authors": [ | ||
| 15 | { | ||
| 16 | "name": "Joshua", | ||
| 17 | "email": "josh@baytech.ph" | ||
| 18 | } | ||
| 19 | ] | ||
| 20 | } |
src/FlagManager.php
0 → 100644
| 1 | <?php | ||
| 2 | namespace BTFlags; | ||
| 3 | |||
| 4 | class FlagManager { | ||
| 5 | |||
| 6 | private $flagsFile; | ||
| 7 | private $errors; | ||
| 8 | |||
| 9 | public function __construct(){ | ||
| 10 | $this->errors = []; | ||
| 11 | $this->flagsFile = FLAGS_DIR . DIRECTORY_SEPARATOR . 'flags.json'; | ||
| 12 | } | ||
| 13 | |||
| 14 | private function checkDir(){ | ||
| 15 | if(!defined("FLAGS_DIR")) throw new \Exception("constant FLAGS_DIR is undefined. Make sure to add it in your constants.php file."); | ||
| 16 | } | ||
| 17 | |||
| 18 | public function create($flagData){ | ||
| 19 | $this->checkDir(); | ||
| 20 | $created = true; | ||
| 21 | $flags = $this->all(); | ||
| 22 | if($flags && count(array_filter($flags, function($flag) use ($flagData){ | ||
| 23 | return $flag['name'] == $flagData['name'] || $flag['encrypted_name'] == $flagData['encrypted_name']; | ||
| 24 | }))){ | ||
| 25 | $this->errors[] = 'Flag already exists.'; | ||
| 26 | return false; | ||
| 27 | } | ||
| 28 | |||
| 29 | try { | ||
| 30 | $flags[] = $flagData; | ||
| 31 | file_put_contents($this->flagsFile, json_encode($flags)); | ||
| 32 | } catch(\Exception $e){ | ||
| 33 | $created = false; | ||
| 34 | $this->errors[] = 'Creating a flag failed. Please try again.'; | ||
| 35 | } | ||
| 36 | |||
| 37 | return $created; | ||
| 38 | } | ||
| 39 | |||
| 40 | public function delete($flagData){ | ||
| 41 | $this->checkDir(); | ||
| 42 | $deleted = true; | ||
| 43 | $flags = $this->all(); | ||
| 44 | if($flags && !count(array_filter($flags, function($flag) use ($flagData){ | ||
| 45 | return $flag['name'] == $flagData['name'] || $flag['encrypted_name'] == $flagData['encrypted_name']; | ||
| 46 | }))){ | ||
| 47 | $this->errors[] = 'Unable to find flag: ' . $flagData['name']; | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | |||
| 51 | $filteredFlags = array_filter($flags, function($flag) use ($flagData){ | ||
| 52 | return $flag['name'] != $flagData['name'] || $flag['encrypted_name'] != $flagData['encrypted_name']; | ||
| 53 | }); | ||
| 54 | |||
| 55 | try { | ||
| 56 | file_put_contents($this->flagsFile, json_encode($filteredFlags)); | ||
| 57 | } catch(\Exception $e){ | ||
| 58 | $deleted = false; | ||
| 59 | $this->errors[] = 'Deleting the flag failed. Please try again.'; | ||
| 60 | } | ||
| 61 | |||
| 62 | return $deleted; | ||
| 63 | } | ||
| 64 | |||
| 65 | public function update($flagData){ | ||
| 66 | $this->checkDir(); | ||
| 67 | $updated = true; | ||
| 68 | $flags = $this->all(); | ||
| 69 | if($flags && !count(array_filter($flags, function($flag) use ($flagData){ | ||
| 70 | return $flag['name'] == $flagData['old_name'] && $flag['encrypted_name'] == $flagData['old_encrypted_name']; | ||
| 71 | }))){ | ||
| 72 | $this->errors[] = 'Unable to find flag: ' . $flagData['old_name']; | ||
| 73 | return false; | ||
| 74 | } | ||
| 75 | |||
| 76 | $filteredFlags = array_filter($flags, function($flag) use ($flagData){ | ||
| 77 | return $flag['name'] == $flagData['old_name'] && $flag['encrypted_name'] == $flagData['old_encrypted_name']; | ||
| 78 | }); | ||
| 79 | |||
| 80 | if(!isset(array_keys($filteredFlags)[0])) return false; | ||
| 81 | |||
| 82 | unset($flagData['old_name']); | ||
| 83 | unset($flagData['old_encrypted_name']); | ||
| 84 | |||
| 85 | try { | ||
| 86 | $flags[array_keys($filteredFlags)[0]] = $flagData; | ||
| 87 | file_put_contents($this->flagsFile, json_encode($flags)); | ||
| 88 | } catch(\Exception $e){ | ||
| 89 | $updated = false; | ||
| 90 | $this->errors[] = 'Updating the flag failed. Please try again.'; | ||
| 91 | } | ||
| 92 | |||
| 93 | return $updated; | ||
| 94 | } | ||
| 95 | |||
| 96 | public function getAllForTable($tableOptions){ | ||
| 97 | $this->checkDir(); | ||
| 98 | $flags = $this->all(); | ||
| 99 | if(!$flags) return []; | ||
| 100 | |||
| 101 | foreach($flags as $index => $flag){ | ||
| 102 | $flags[$index]['combined_values'] = !$flags[$index]['is_filtered'] ? 'Anything' : ''; | ||
| 103 | if(!$flags[$index]['is_filtered']) continue; | ||
| 104 | foreach($flag['accepted_values'] as $acceptedValue){ | ||
| 105 | if(is_null($acceptedValue['value']) || !trim($acceptedValue['value'])) continue; | ||
| 106 | $flags[$index]['combined_values'] .= $acceptedValue['value'] . ' -> ' . $acceptedValue['encrypted_value'] . '<br>'; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | $flags = $this->filterFlags($flags, $tableOptions); | ||
| 111 | |||
| 112 | return array_slice($flags, (($tableOptions['page'] - 1) * $tableOptions['perPage']), $tableOptions['perPage']); | ||
| 113 | } | ||
| 114 | |||
| 115 | private function filterFlags($flags, $tableOptions){ | ||
| 116 | $this->checkDir(); | ||
| 117 | if(!empty($tableOptions['filter'])){ | ||
| 118 | $filter = $tableOptions['filter']; | ||
| 119 | $flags = array_filter($flags, function($flag) use ($filter) { | ||
| 120 | return trim($flag['name']) == trim($filter) || trim($flag['encrypted_name']) == trim($filter); | ||
| 121 | }); | ||
| 122 | } | ||
| 123 | return $flags; | ||
| 124 | } | ||
| 125 | |||
| 126 | public function getAllCountForTable($tableOptions){ | ||
| 127 | $this->checkDir(); | ||
| 128 | $flags = $this->all(); | ||
| 129 | if(!$flags) return 0; | ||
| 130 | |||
| 131 | $flags = $this->filterFlags($flags, $tableOptions); | ||
| 132 | |||
| 133 | return count($flags); | ||
| 134 | } | ||
| 135 | |||
| 136 | public function all(){ | ||
| 137 | $this->checkDir(); | ||
| 138 | $flags = []; | ||
| 139 | $retrieved = true; | ||
| 140 | try { | ||
| 141 | $flags = json_decode(@file_get_contents($this->flagsFile), true); | ||
| 142 | } catch(\Exception $e){ | ||
| 143 | $retrieved = false; | ||
| 144 | $this->errors[] = 'Cannot retrieve flags. Please try again'; | ||
| 145 | } | ||
| 146 | return $retrieved ? $flags : false; | ||
| 147 | } | ||
| 148 | |||
| 149 | public function errors(){ | ||
| 150 | return $this->errors; | ||
| 151 | } | ||
| 152 | |||
| 153 | public function register(){ | ||
| 154 | $this->checkDir(); | ||
| 155 | $flags = $this->all(); | ||
| 156 | if(!$flags) return []; | ||
| 157 | foreach($flags as $flag){ | ||
| 158 | $value = $this->checkFlag($flag, !empty($flag['default']) ? $flag['default'] : null); | ||
| 159 | setcookie($flag['encrypted_name'], $value, time() + (86400 * 30), "/"); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | private function filterFlag($flag, $needle, $defaultValue){ | ||
| 164 | $this->checkDir(); | ||
| 165 | if(!$flag['is_filtered']) return $needle; | ||
| 166 | |||
| 167 | $acceptedValues = $flag['accepted_values']; | ||
| 168 | return count(array_filter($acceptedValues, function($value) use ($needle) { | ||
| 169 | return $value['encrypted_value'] == $needle; | ||
| 170 | })) ? $needle : $defaultValue; | ||
| 171 | } | ||
| 172 | |||
| 173 | public function checkFlag($flag, $defaultValue, $driver = 'cookie'){ | ||
| 174 | $this->checkDir(); | ||
| 175 | $flagEncryptedName = $flag['encrypted_name']; | ||
| 176 | // Cookie Driver | ||
| 177 | if($driver == 'cookie') return !empty($_GET[$flagEncryptedName]) ? $this->filterFlag($flag, $_GET[$flagEncryptedName], $defaultValue) : (!empty($_COOKIE[$flagEncryptedName]) ? $this->filterFlag($flag, $_COOKIE[$flagEncryptedName], $defaultValue) : $defaultValue); | ||
| 178 | // Session Driver | ||
| 179 | return !empty($_GET[$flagEncryptedName]) ? $this->filterFlag($flag, $_GET[$flagEncryptedName], $defaultValue) : ($_SESSION[$flagEncryptedName] ? $this->filterFlag($flag, $_SESSION[$flagEncryptedName], $defaultValue) : $defaultValue); | ||
| 180 | } | ||
| 181 | |||
| 182 | private function filter($flag, $value, $default){ | ||
| 183 | $this->checkDir(); | ||
| 184 | $filters = [ | ||
| 185 | 'pmt' => ['rec', 'st'] | ||
| 186 | ]; | ||
| 187 | if(isset($filters[$flag])) return (in_array($value, $filters[$flag]))? $value:$default; | ||
| 188 | return $value; | ||
| 189 | } | ||
| 190 | |||
| 191 | public function getFlag($flag, $encrypted){ | ||
| 192 | $this->checkDir(); | ||
| 193 | $flags = $this->all(); | ||
| 194 | if(!$flags) return []; | ||
| 195 | $filteredFlags = array_values(array_filter($flags, function($f) use ($flag, $encrypted){ | ||
| 196 | return ($encrypted ? $f['encrypted_name'] : $f['name']) == $flag; | ||
| 197 | })); | ||
| 198 | return count($filteredFlags) ? $filteredFlags[0] : null; | ||
| 199 | } | ||
| 200 | |||
| 201 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/Flags.php
0 → 100644
| 1 | <?php | ||
| 2 | namespace BTFlags; | ||
| 3 | use BTFlags\FlagManager; | ||
| 4 | |||
| 5 | class Flags{ | ||
| 6 | |||
| 7 | /** | ||
| 8 | * Retrieves the decrypted value of a flag | ||
| 9 | * | ||
| 10 | * @param string $flag Name of the flag. | ||
| 11 | * @param bool $encrypted True, if the passed $flag is an encrypted value. | ||
| 12 | * @param string $defaultValue Default value of a flag if the flag does not exist in the specified storage driver. | ||
| 13 | * @param string $driver Storage driver. | ||
| 14 | * | ||
| 15 | * @return string | ||
| 16 | */ | ||
| 17 | public static function get($flagName, $encrypted = false, $defaultValue, $driver = 'cookie'){ | ||
| 18 | $flagManager = new FlagManager(); | ||
| 19 | $flag = $flagManager->getFlag($flagName, $encrypted); | ||
| 20 | if(!$flag) return null; | ||
| 21 | $flagFromStorage = self::findFlagFromStorage($encrypted ? $flagName : $flag['encrypted_name'], $defaultValue ? $defaultValue : (isset($flag['has_default']) && $flag['has_default'] ? $flag['default'] : null), $driver); | ||
| 22 | if(!$flag['is_filtered']) return $flagFromStorage; | ||
| 23 | |||
| 24 | $filteredFlag = null; | ||
| 25 | if($flag['is_filtered']){ | ||
| 26 | $filteredFlag = array_values(array_filter($flag['accepted_values'], function($value) use ($flagFromStorage, $encrypted){ return $value['encrypted_value'] == $flagFromStorage; })); | ||
| 27 | } | ||
| 28 | $filteredValue = array_values(array_filter($flag['accepted_values'], function($value) use ($flag){ return $value['encrypted_value'] == $flag['default']; })); | ||
| 29 | |||
| 30 | return $filteredFlag && isset($filteredFlag[0]) ? $filteredFlag[0]['value'] : ($flag['is_encrypted'] && isset($filteredValue[0]['value']) ? $filteredValue[0]['value'] : $flag['default']); | ||
| 31 | } | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Look for the flag inside the specified storage driver. | ||
| 35 | * | ||
| 36 | * @param string $flag Name of the flag. | ||
| 37 | * @param string $defaultValue Default value of a flag if the flag does not exist in the specified storage driver. | ||
| 38 | * @param string $driver Storage driver. | ||
| 39 | * | ||
| 40 | * @return string | ||
| 41 | */ | ||
| 42 | private static function findFlagFromStorage($flag, $defaultValue, $driver){ | ||
| 43 | // Cookie Driver | ||
| 44 | if($driver == 'cookie') return isset($_GET[$flag]) ? $_GET[$flag] : (isset($_COOKIE[$flag]) ? $_COOKIE[$flag] : $defaultValue); | ||
| 45 | // Session Driver | ||
| 46 | return isset($_GET[$flag]) ? $_GET[$flag] : ($_SESSION[$flag] ? $_SESSION[$flag] : $defaultValue); | ||
| 47 | } | ||
| 48 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment