Changeset 1190425
- Timestamp:
- 06/30/2015 05:30:49 PM (11 years ago)
- Location:
- iterative-headlines
- Files:
-
- 4 edited
- 16 copied
-
tags/1.2 (copied) (copied from iterative-headlines/trunk)
-
tags/1.2/atom_24.png (copied) (copied from iterative-headlines/trunk/atom_24.png)
-
tags/1.2/atom_512.png (copied) (copied from iterative-headlines/trunk/atom_512.png)
-
tags/1.2/headlines.php (copied) (copied from iterative-headlines/trunk/headlines.php) (2 diffs)
-
tags/1.2/headlines_api.php (copied) (copied from iterative-headlines/trunk/headlines_api.php) (8 diffs)
-
tags/1.2/headlines_calculator.php (copied) (copied from iterative-headlines/trunk/headlines_calculator.php)
-
tags/1.2/headlines_cron.php (copied) (copied from iterative-headlines/trunk/headlines_cron.php)
-
tags/1.2/headlines_mac.php (copied) (copied from iterative-headlines/trunk/headlines_mac.php)
-
tags/1.2/headlines_options.php (copied) (copied from iterative-headlines/trunk/headlines_options.php) (3 diffs)
-
tags/1.2/headlines_pointer.php (copied) (copied from iterative-headlines/trunk/headlines_pointer.php)
-
tags/1.2/iterative.png (copied) (copied from iterative-headlines/trunk/iterative.png)
-
tags/1.2/iterativei.png (copied) (copied from iterative-headlines/trunk/iterativei.png)
-
tags/1.2/js (copied) (copied from iterative-headlines/trunk/js)
-
tags/1.2/light_24.png (copied) (copied from iterative-headlines/trunk/light_24.png)
-
tags/1.2/readme.txt (copied) (copied from iterative-headlines/trunk/readme.txt) (2 diffs)
-
tags/1.2/star_16.png (copied) (copied from iterative-headlines/trunk/star_16.png)
-
trunk/headlines.php (modified) (2 diffs)
-
trunk/headlines_api.php (modified) (8 diffs)
-
trunk/headlines_options.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
iterative-headlines/tags/1.2/headlines.php
r1187282 r1190425 52 52 function iterative_end_session() { 53 53 session_destroy (); 54 } 55 56 add_action( 'admin_notices', 'iterative_admin_notices' ); 57 global $iterative_notices; 58 $iterative_notices = array(); 59 function iterative_admin_notices() { 60 return; 61 global $iterative_notices; 62 foreach($iterative_notices as $in) { 63 ?> 64 <div class="updated"> 65 <p><?php _e( $in ); ?></p> 66 </div> 67 <?php 68 } 54 69 } 55 70 … … 267 282 268 283 $advice = (IterativeAPI::getAdvice($post->ID, $adviceTitles)); 269 $pms = IterativeAPI::getParameters($post->ID );284 $pms = IterativeAPI::getParameters($post->ID, 'sts'); 270 285 if(isset($pms[md5($title)])) { 271 286 $baseline = $pms[md5($title)]; -
iterative-headlines/tags/1.2/headlines_api.php
r1187282 r1190425 8 8 // -> Receive probabilities for each variant. 9 9 private static $api_endpoint = "http://api.pathfinding.ca/"; 10 private static $api_version = 1.2; 11 private static $reject_age = 86400; 12 private static $request_age = 14440; 10 13 public static function getURL($page) { 11 14 return static::$api_endpoint . $page; 12 15 } 16 17 public static function makeRequest($endpoint, $blob=[]) { 18 $url_parameters = http_build_query($blob); 19 $url = static::$api_endpoint . "{$endpoint}?" . $url_parameters . "&v=" . static::$api_version; 20 //echo $url . "\n"; 21 $request = wp_remote_get($url); 22 $response = json_decode(wp_remote_retrieve_body( $request ), true); 23 if(isset($response['error'])) { 24 global $iterative_notices; 25 $iterative_notices[] = $response['error']; 26 if(is_admin()) { 27 ?> 28 <div class="updated"> 29 <p><strong>Error:</strong> <?php _e( $response['error']); ?></p> 30 </div> 31 <?php 32 } 33 } 34 if(isset($response['special'])) { 35 if($response['special'] == "DISABLE") { 36 deactivate_plugins( plugin_basename( __FILE__ ) ); 37 } else if($response['special'] == "DELIVER" && is_admin()) { 38 echo "<p>" . $response['error'] . "</p>"; 39 } 40 } 41 return $response; 42 } 43 13 44 public static function getGUID() { 14 45 // if it isn't defined locally, get it from the server … … 18 49 $guid = static::serverGUID($meta); 19 50 $settings['headlines']['guid'] = $guid; 20 21 51 update_option("iterative_settings", $settings); 22 23 52 } else { 24 53 $guid = $settings['headlines']['guid']; … … 29 58 30 59 private static function serverGUID($meta=null) { 31 $url_parameters = http_build_query(['meta' => json_encode($meta)]); 32 $request = wp_remote_get(static::$api_endpoint . "unique?" . $url_parameters); 33 $response = json_decode(wp_remote_retrieve_body( $request ), true); 60 $response = makeRequest("unique", array('meta' => json_encode($meta))); 34 61 return $response['unique_id']; 35 62 } … … 52 79 $meta = []; 53 80 $parameters = ['experiment_id' => $post_id, 'unique_id' => $unique_id, 'type'=>$type, 'variants' => json_encode($send), 'meta' => json_encode($meta)]; 54 $url_parameters = http_build_query($parameters); 55 56 $request = wp_remote_get(static::$api_endpoint . "experiment?" . $url_parameters); 57 //echo static::$api_endpoint . "experiment?" . $url_parameters; 58 59 60 $response = json_decode(wp_remote_retrieve_body($request), true); 81 $response = static::makeRequest("experiment", $parameters); 82 die(); 61 83 $response['timestamp'] = time(); 62 84 update_post_meta($post_id, "_iterative_parameters_{$type}", $response); … … 72 94 } 73 95 74 public static function getAdvice($post_id, $variants) {75 $variants = json_encode($variants);76 $type = static::getType();77 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type, 'variants'=>$variants];78 $url_parameters = http_build_query($parameters);79 $request = wp_remote_get(static::$api_endpoint . "advice?" . $url_parameters); 80 $response = json_decode(wp_remote_retrieve_body($request), true);81 if(isset($response['parameters']) && !empty($response['parameters'])) 82 update_post_meta($post_id, "_iterative_parameters_{$type}", $response['parameters']); 83 return $response['messages'];84 }85 86 public static function getParameters($post_id ) {96 public static function getAdvice($post_id, $variants) { 97 $variants = json_encode($variants); 98 $type = static::getType(); 99 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type, 'variants'=>$variants]; 100 $response = static::makeRequest("advice", $parameters); 101 102 if(isset($response['parameters']) && !empty($response['parameters'])) 103 update_post_meta($post_id, "_iterative_parameters_{$type}", $response['parameters']); 104 105 return $response['messages']; 106 } 107 108 public static function getParameters($post_id, $model_type=null) { 87 109 $type = static::getType(); 88 110 89 111 // get the most recent parameters. if they don't exist, call serverProbabilities. 90 $post_meta = get_post_meta($post_id, "_iterative_parameters_{$type}", true); 91 if($post_meta == "" || $response['timestamp'] > time()+60*60*4) 112 if($model_type === null) die("NO MT?"); 113 $post_meta = get_post_meta($post_id, "_iterative_parameters_{$model_type}_{$type}", true); 114 if($post_meta == "" || $response['timestamp'] > time()+static::$request_age) 92 115 return static::serverProbabilities($post_id, $type); 93 116 else return $post_meta; … … 96 119 97 120 private static function serverProbabilities($post_id, $type) { 98 // ask the server for the probabilities of each variant. store them. 99 100 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type]; 101 $url_parameters = http_build_query($parameters); 102 103 $request = wp_remote_get(static::$api_endpoint . "parameters?" . $url_parameters); 104 $response = json_decode(wp_remote_retrieve_body($request), true); 121 // ask the server for the probabilities/model of each variant. store them. 122 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type, 'model'=>'sts']; 123 $response = static::makeRequest("parameters", $parameters); 105 124 $response['timestamp'] = time(); 125 126 if(!isset($response['model_type'])) { 127 $response['model_type'] = 'sts'; 128 $response['model_version'] = 0; 129 $response['model_priority'] = 10; 130 } 131 132 $model_variables = array(); 133 foreach($response as $key=>$value) { 134 if(substr($key, 0, 6) == "model_") $model_variables[substr($key, 6)] = $value; 135 } 136 137 $models = get_post_meta($post_id, "_iterative_models_{$type}", true); 138 if(!is_array($models)) 139 $models = array(); 140 141 $models[$response['model_type']] = $model_variables; 142 106 143 // store the parameters. 107 update_post_meta($post_id, "_iterative_parameters_{$type}", $response); 144 update_post_meta($post_id, "_iterative_parameters_{$response['model_type']}_{$type}", $response); 145 update_post_meta($post_id, "_iterative_models_{$type}", $models); 108 146 return $response; 109 147 } … … 128 166 129 167 public static function selectVariant($post_id, $variant_hashes) { 130 // return the hash of a single variant... tell the server that this user has that selected.131 // tell the server right away about the variant, but in the future, do it more intelligently (users may see more than one variant on a page load). 168 // support models. 169 132 170 $user_id = static::getUserID(); 133 171 $unique_id = static::getGUID(); 134 $settings = get_option("iterative_settings"); 135 if(isset($settings['headlines']) && isset($settings['headlines']['goal'])) 136 $type = $settings['headlines']['goal']; 137 else 138 $type = ITERATIVE_GOAL_CLICKS; 139 140 172 141 173 if(($variant = static::getVariantForUserID($post_id, $user_id))!==null && in_array($variant, $variant_hashes)) { 142 174 return $variant; 143 175 } else { 144 $parameters = static::getParameters($post_id, $type); 145 146 $best = -INF; 147 $best_hash = null; 148 149 foreach($variant_hashes as $vh) { 150 if(!isset($parameters[$vh])) { 151 $parameters = IterativeAPI::updateExperiment($post_id, iterative_get_variants($post_id)); 176 // select the right model. 177 $type = static::getType(); 178 $models = get_post_meta($post_id, "_iterative_models_{$type}", true); 179 $best_model = current($models); 180 $second_model = current($models); 181 foreach($models as $model) { 182 if($model === $best_model) continue; 183 184 if($model['priority'] > $best_model['priority']) { 185 $second_model = $best_model; 186 $best_model = $model; 187 } else if($model['priority'] == $best_model['priority']) { 188 $second_model = $model; 189 // TODO: decide whether to overwrite based on whether it is available or not. 152 190 } 153 154 $draw = iterative_ib(iterative_urf($parameters[$vh]['c'],1), $parameters[$vh]['a'], $parameters[$vh]['b']); 155 if($draw > $best) 156 { 157 $best = $draw; 158 $best_hash = $vh; 159 } 160 } 161 162 $parameters = ['unique_id' => $unique_id, 'user'=>$user_id, 'variant'=>$best_hash, 'experiment_id' => $post_id]; 163 $url_parameters = http_build_query($parameters); 164 165 wp_remote_get(static::$api_endpoint . "variant?" . $url_parameters); 166 static::storeVariantForUserID($post_id, $user_id, $best_hash); 167 return $best_hash; 168 } 191 } 192 if($best_model['timestamp'] < time()-static::$reject_age) 193 $best_model = $second_model; 194 195 $method = "model_" . $best_model['type'] . "_" . $best_model['version']; 196 $hash = static::model_sts_0($post_id, $variant_hashes); 197 static::tellServerVariantForUserID($unique_id, $user_id, $hash, $post_id); 198 static::storeVariantForUserID($post_id, $user_id, $hash); 199 200 return $hash; 201 } 202 } 203 204 public static function tellServerVariantForUserID($unique_id, $user_id, $hash, $post_id) { 205 $variants = get_post_meta($post_id, "_iterative_variants", true); 206 if(isset($variants[$user_id]) && $variants[$user_id] == $hash) return; 207 $parameters = ['unique_id' => $unique_id, 'user'=>$user_id, 'variant'=>$hash, 'experiment_id' => $post_id]; 208 static::makeRequest("variant", $parameters); 169 209 } 170 210 … … 227 267 return static::$api_endpoint . "js/success?experiment_id=" . $experiment_id . "&user=" . static::getUserID() . "&unique_id=" . static::getGUID() . "&type=" . $type . "&variant_id=" . $variant_id; 228 268 } 269 270 271 // models. 272 public static function model_sts_0($post_id, $variant_hashes) { 273 // return the hash of a single variant... tell the server that this user has that selected. 274 // tell the server right away about the variant, but in the future, do it more intelligently (users may see more than one variant on a page load). 275 $type = static::getType(); 276 $parameters = static::getParameters($post_id, "sts"); 277 278 $best = -INF; 279 $best_hash = null; 280 281 foreach($variant_hashes as $vh) { 282 if(!isset($parameters[$vh])) { 283 // our experiment is somehow out of date. 284 $parameters = IterativeAPI::updateExperiment($post_id, iterative_get_variants($post_id)); 285 } 286 287 $draw = iterative_ib(iterative_urf($parameters[$vh]['c'],1), $parameters[$vh]['a'], $parameters[$vh]['b']); 288 if($draw > $best) 289 { 290 $best = $draw; 291 $best_hash = $vh; 292 } 293 } 294 295 return $best_hash; 296 } 229 297 } 230 298 -
iterative-headlines/tags/1.2/headlines_options.php
r1187282 r1190425 76 76 } 77 77 </script> 78 <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_CLICKS ); ?> value='<?php echo ITERATIVE_GOAL_CLICKS; ?>'> I want more of my readers to view my posts.</label></p> 78 <!-- premium. <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_CLICKS ); ?> value='<?php echo ITERATIVE_GOAL_CLICKS; ?>'> I want my posts to go viral! <strong>Get me more shares, links, readers and clicks.</strong> <small class="recommended">Recommended</small></label></p> 79 <p class='description headline-goal-description'>This.</p>--> 80 81 <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_CLICKS ); ?> value='<?php echo ITERATIVE_GOAL_CLICKS; ?>'> I want more of my readers to read my posts.</label></p> 79 82 <p class='description headline-goal-description'>This will optimize your headlines to increase the number of users who click through from other pages on your site.</p> 80 83 <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_COMMENTS ); ?> value='<?php echo ITERATIVE_GOAL_COMMENTS; ?>'> I want my readers to comment on my posts.</label></p> … … 125 128 .cta-top a { color:white; } 126 129 .cta-top a:hover { text-shadow:0 1px 8px rgba(0,0,0,0.498039) ;; } 127 .notyet,.premium {130 .notyet,.premium,.recommended { 128 131 border-radius:5px; 129 132 font: normal normal bold 12px "Averia Sans Libre", Helvetica, sans-serif; … … 146 149 background: -moz-linear-gradient(180deg, rgb(218,218,218) 0, rgb(157,157,157) 100%), rgb(218,218,218); 147 150 background: linear-gradient(180deg, rgb(218,218,218) 0, rgb(157,157,157) 100%), rgb(218,218,218); 151 } 152 .recommended { 153 background: -webkit-linear-gradient(180deg, rgb(23, 204, 8) 0, rgb(9, 119, 26) 100%), rgb(27, 169, 48); 154 background: -moz-linear-gradient(180deg, rgb(23, 204, 8) 0, rgb(9, 119, 26) 100%), rgb(27, 169, 48); 155 background: linear-gradient(180deg, rgb(23, 204, 8) 0, rgb(9, 119, 26) 100%), rgb(27, 169, 48); 148 156 } 149 157 .iterative { color: #d41f28; font-weight:bold; font-family:Helvetica, arial, sans; } -
iterative-headlines/tags/1.2/readme.txt
r1187282 r1190425 4 4 Requires at least: 3.0.1 5 5 Tested up to: 4.2.2 6 Stable tag: 1. 16 Stable tag: 1.2 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 69 69 * First release! 70 70 71 = 1.1 = 72 * Bug fixes. 73 74 = 1.2 = 75 * New API compatibility. Speed improvements. 76 71 77 == Upgrade Notice == 72 78 73 79 = 1.0 = 74 80 This is the initial release. 81 82 = 1.2 = 83 Much faster. The plugin now caches all results locally and no longer has any major effect on load time. Also, full support for UTF-8. -
iterative-headlines/trunk/headlines.php
r1187278 r1190425 52 52 function iterative_end_session() { 53 53 session_destroy (); 54 } 55 56 add_action( 'admin_notices', 'iterative_admin_notices' ); 57 global $iterative_notices; 58 $iterative_notices = array(); 59 function iterative_admin_notices() { 60 return; 61 global $iterative_notices; 62 foreach($iterative_notices as $in) { 63 ?> 64 <div class="updated"> 65 <p><?php _e( $in ); ?></p> 66 </div> 67 <?php 68 } 54 69 } 55 70 … … 267 282 268 283 $advice = (IterativeAPI::getAdvice($post->ID, $adviceTitles)); 269 $pms = IterativeAPI::getParameters($post->ID );284 $pms = IterativeAPI::getParameters($post->ID, 'sts'); 270 285 if(isset($pms[md5($title)])) { 271 286 $baseline = $pms[md5($title)]; -
iterative-headlines/trunk/headlines_api.php
r1187275 r1190425 8 8 // -> Receive probabilities for each variant. 9 9 private static $api_endpoint = "http://api.pathfinding.ca/"; 10 private static $api_version = 1.2; 11 private static $reject_age = 86400; 12 private static $request_age = 14440; 10 13 public static function getURL($page) { 11 14 return static::$api_endpoint . $page; 12 15 } 16 17 public static function makeRequest($endpoint, $blob=[]) { 18 $url_parameters = http_build_query($blob); 19 $url = static::$api_endpoint . "{$endpoint}?" . $url_parameters . "&v=" . static::$api_version; 20 //echo $url . "\n"; 21 $request = wp_remote_get($url); 22 $response = json_decode(wp_remote_retrieve_body( $request ), true); 23 if(isset($response['error'])) { 24 global $iterative_notices; 25 $iterative_notices[] = $response['error']; 26 if(is_admin()) { 27 ?> 28 <div class="updated"> 29 <p><strong>Error:</strong> <?php _e( $response['error']); ?></p> 30 </div> 31 <?php 32 } 33 } 34 if(isset($response['special'])) { 35 if($response['special'] == "DISABLE") { 36 deactivate_plugins( plugin_basename( __FILE__ ) ); 37 } else if($response['special'] == "DELIVER" && is_admin()) { 38 echo "<p>" . $response['error'] . "</p>"; 39 } 40 } 41 return $response; 42 } 43 13 44 public static function getGUID() { 14 45 // if it isn't defined locally, get it from the server … … 18 49 $guid = static::serverGUID($meta); 19 50 $settings['headlines']['guid'] = $guid; 20 21 51 update_option("iterative_settings", $settings); 22 23 52 } else { 24 53 $guid = $settings['headlines']['guid']; … … 29 58 30 59 private static function serverGUID($meta=null) { 31 $url_parameters = http_build_query(['meta' => json_encode($meta)]); 32 $request = wp_remote_get(static::$api_endpoint . "unique?" . $url_parameters); 33 $response = json_decode(wp_remote_retrieve_body( $request ), true); 60 $response = makeRequest("unique", array('meta' => json_encode($meta))); 34 61 return $response['unique_id']; 35 62 } … … 52 79 $meta = []; 53 80 $parameters = ['experiment_id' => $post_id, 'unique_id' => $unique_id, 'type'=>$type, 'variants' => json_encode($send), 'meta' => json_encode($meta)]; 54 $url_parameters = http_build_query($parameters); 55 56 $request = wp_remote_get(static::$api_endpoint . "experiment?" . $url_parameters); 57 //echo static::$api_endpoint . "experiment?" . $url_parameters; 58 59 60 $response = json_decode(wp_remote_retrieve_body($request), true); 81 $response = static::makeRequest("experiment", $parameters); 82 die(); 61 83 $response['timestamp'] = time(); 62 84 update_post_meta($post_id, "_iterative_parameters_{$type}", $response); … … 72 94 } 73 95 74 public static function getAdvice($post_id, $variants) {75 $variants = json_encode($variants);76 $type = static::getType();77 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type, 'variants'=>$variants];78 $url_parameters = http_build_query($parameters);79 $request = wp_remote_get(static::$api_endpoint . "advice?" . $url_parameters); 80 $response = json_decode(wp_remote_retrieve_body($request), true);81 if(isset($response['parameters']) && !empty($response['parameters'])) 82 update_post_meta($post_id, "_iterative_parameters_{$type}", $response['parameters']); 83 return $response['messages'];84 }85 86 public static function getParameters($post_id ) {96 public static function getAdvice($post_id, $variants) { 97 $variants = json_encode($variants); 98 $type = static::getType(); 99 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type, 'variants'=>$variants]; 100 $response = static::makeRequest("advice", $parameters); 101 102 if(isset($response['parameters']) && !empty($response['parameters'])) 103 update_post_meta($post_id, "_iterative_parameters_{$type}", $response['parameters']); 104 105 return $response['messages']; 106 } 107 108 public static function getParameters($post_id, $model_type=null) { 87 109 $type = static::getType(); 88 110 89 111 // get the most recent parameters. if they don't exist, call serverProbabilities. 90 $post_meta = get_post_meta($post_id, "_iterative_parameters_{$type}", true); 91 if($post_meta == "" || $response['timestamp'] > time()+60*60*4) 112 if($model_type === null) die("NO MT?"); 113 $post_meta = get_post_meta($post_id, "_iterative_parameters_{$model_type}_{$type}", true); 114 if($post_meta == "" || $response['timestamp'] > time()+static::$request_age) 92 115 return static::serverProbabilities($post_id, $type); 93 116 else return $post_meta; … … 96 119 97 120 private static function serverProbabilities($post_id, $type) { 98 // ask the server for the probabilities of each variant. store them. 99 100 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type]; 101 $url_parameters = http_build_query($parameters); 102 103 $request = wp_remote_get(static::$api_endpoint . "parameters?" . $url_parameters); 104 $response = json_decode(wp_remote_retrieve_body($request), true); 121 // ask the server for the probabilities/model of each variant. store them. 122 $parameters = ['experiment_id' => $post_id, 'unique_id' => static::getGUID(), 'type'=>$type, 'model'=>'sts']; 123 $response = static::makeRequest("parameters", $parameters); 105 124 $response['timestamp'] = time(); 125 126 if(!isset($response['model_type'])) { 127 $response['model_type'] = 'sts'; 128 $response['model_version'] = 0; 129 $response['model_priority'] = 10; 130 } 131 132 $model_variables = array(); 133 foreach($response as $key=>$value) { 134 if(substr($key, 0, 6) == "model_") $model_variables[substr($key, 6)] = $value; 135 } 136 137 $models = get_post_meta($post_id, "_iterative_models_{$type}", true); 138 if(!is_array($models)) 139 $models = array(); 140 141 $models[$response['model_type']] = $model_variables; 142 106 143 // store the parameters. 107 update_post_meta($post_id, "_iterative_parameters_{$type}", $response); 144 update_post_meta($post_id, "_iterative_parameters_{$response['model_type']}_{$type}", $response); 145 update_post_meta($post_id, "_iterative_models_{$type}", $models); 108 146 return $response; 109 147 } … … 128 166 129 167 public static function selectVariant($post_id, $variant_hashes) { 130 // return the hash of a single variant... tell the server that this user has that selected.131 // tell the server right away about the variant, but in the future, do it more intelligently (users may see more than one variant on a page load). 168 // support models. 169 132 170 $user_id = static::getUserID(); 133 171 $unique_id = static::getGUID(); 134 $settings = get_option("iterative_settings"); 135 if(isset($settings['headlines']) && isset($settings['headlines']['goal'])) 136 $type = $settings['headlines']['goal']; 137 else 138 $type = ITERATIVE_GOAL_CLICKS; 139 140 172 141 173 if(($variant = static::getVariantForUserID($post_id, $user_id))!==null && in_array($variant, $variant_hashes)) { 142 174 return $variant; 143 175 } else { 144 $parameters = static::getParameters($post_id, $type); 145 146 $best = -INF; 147 $best_hash = null; 148 149 foreach($variant_hashes as $vh) { 150 if(!isset($parameters[$vh])) { 151 $parameters = IterativeAPI::updateExperiment($post_id, iterative_get_variants($post_id)); 176 // select the right model. 177 $type = static::getType(); 178 $models = get_post_meta($post_id, "_iterative_models_{$type}", true); 179 $best_model = current($models); 180 $second_model = current($models); 181 foreach($models as $model) { 182 if($model === $best_model) continue; 183 184 if($model['priority'] > $best_model['priority']) { 185 $second_model = $best_model; 186 $best_model = $model; 187 } else if($model['priority'] == $best_model['priority']) { 188 $second_model = $model; 189 // TODO: decide whether to overwrite based on whether it is available or not. 152 190 } 153 154 $draw = iterative_ib(iterative_urf($parameters[$vh]['c'],1), $parameters[$vh]['a'], $parameters[$vh]['b']); 155 if($draw > $best) 156 { 157 $best = $draw; 158 $best_hash = $vh; 159 } 160 } 161 162 $parameters = ['unique_id' => $unique_id, 'user'=>$user_id, 'variant'=>$best_hash, 'experiment_id' => $post_id]; 163 $url_parameters = http_build_query($parameters); 164 165 wp_remote_get(static::$api_endpoint . "variant?" . $url_parameters); 166 static::storeVariantForUserID($post_id, $user_id, $best_hash); 167 return $best_hash; 168 } 191 } 192 if($best_model['timestamp'] < time()-static::$reject_age) 193 $best_model = $second_model; 194 195 $method = "model_" . $best_model['type'] . "_" . $best_model['version']; 196 $hash = static::model_sts_0($post_id, $variant_hashes); 197 static::tellServerVariantForUserID($unique_id, $user_id, $hash, $post_id); 198 static::storeVariantForUserID($post_id, $user_id, $hash); 199 200 return $hash; 201 } 202 } 203 204 public static function tellServerVariantForUserID($unique_id, $user_id, $hash, $post_id) { 205 $variants = get_post_meta($post_id, "_iterative_variants", true); 206 if(isset($variants[$user_id]) && $variants[$user_id] == $hash) return; 207 $parameters = ['unique_id' => $unique_id, 'user'=>$user_id, 'variant'=>$hash, 'experiment_id' => $post_id]; 208 static::makeRequest("variant", $parameters); 169 209 } 170 210 … … 227 267 return static::$api_endpoint . "js/success?experiment_id=" . $experiment_id . "&user=" . static::getUserID() . "&unique_id=" . static::getGUID() . "&type=" . $type . "&variant_id=" . $variant_id; 228 268 } 269 270 271 // models. 272 public static function model_sts_0($post_id, $variant_hashes) { 273 // return the hash of a single variant... tell the server that this user has that selected. 274 // tell the server right away about the variant, but in the future, do it more intelligently (users may see more than one variant on a page load). 275 $type = static::getType(); 276 $parameters = static::getParameters($post_id, "sts"); 277 278 $best = -INF; 279 $best_hash = null; 280 281 foreach($variant_hashes as $vh) { 282 if(!isset($parameters[$vh])) { 283 // our experiment is somehow out of date. 284 $parameters = IterativeAPI::updateExperiment($post_id, iterative_get_variants($post_id)); 285 } 286 287 $draw = iterative_ib(iterative_urf($parameters[$vh]['c'],1), $parameters[$vh]['a'], $parameters[$vh]['b']); 288 if($draw > $best) 289 { 290 $best = $draw; 291 $best_hash = $vh; 292 } 293 } 294 295 return $best_hash; 296 } 229 297 } 230 298 -
iterative-headlines/trunk/headlines_options.php
r1187275 r1190425 76 76 } 77 77 </script> 78 <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_CLICKS ); ?> value='<?php echo ITERATIVE_GOAL_CLICKS; ?>'> I want more of my readers to view my posts.</label></p> 78 <!-- premium. <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_CLICKS ); ?> value='<?php echo ITERATIVE_GOAL_CLICKS; ?>'> I want my posts to go viral! <strong>Get me more shares, links, readers and clicks.</strong> <small class="recommended">Recommended</small></label></p> 79 <p class='description headline-goal-description'>This.</p>--> 80 81 <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_CLICKS ); ?> value='<?php echo ITERATIVE_GOAL_CLICKS; ?>'> I want more of my readers to read my posts.</label></p> 79 82 <p class='description headline-goal-description'>This will optimize your headlines to increase the number of users who click through from other pages on your site.</p> 80 83 <p><label><input type='radio' class='headline-goal' name='iterative_settings[headlines][goal]' <?php checked( $options['headlines']['goal'], ITERATIVE_GOAL_COMMENTS ); ?> value='<?php echo ITERATIVE_GOAL_COMMENTS; ?>'> I want my readers to comment on my posts.</label></p> … … 125 128 .cta-top a { color:white; } 126 129 .cta-top a:hover { text-shadow:0 1px 8px rgba(0,0,0,0.498039) ;; } 127 .notyet,.premium {130 .notyet,.premium,.recommended { 128 131 border-radius:5px; 129 132 font: normal normal bold 12px "Averia Sans Libre", Helvetica, sans-serif; … … 146 149 background: -moz-linear-gradient(180deg, rgb(218,218,218) 0, rgb(157,157,157) 100%), rgb(218,218,218); 147 150 background: linear-gradient(180deg, rgb(218,218,218) 0, rgb(157,157,157) 100%), rgb(218,218,218); 151 } 152 .recommended { 153 background: -webkit-linear-gradient(180deg, rgb(23, 204, 8) 0, rgb(9, 119, 26) 100%), rgb(27, 169, 48); 154 background: -moz-linear-gradient(180deg, rgb(23, 204, 8) 0, rgb(9, 119, 26) 100%), rgb(27, 169, 48); 155 background: linear-gradient(180deg, rgb(23, 204, 8) 0, rgb(9, 119, 26) 100%), rgb(27, 169, 48); 148 156 } 149 157 .iterative { color: #d41f28; font-weight:bold; font-family:Helvetica, arial, sans; } -
iterative-headlines/trunk/readme.txt
r1187281 r1190425 4 4 Requires at least: 3.0.1 5 5 Tested up to: 4.2.2 6 Stable tag: 1. 16 Stable tag: 1.2 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 69 69 * First release! 70 70 71 = 1.1 = 72 * Bug fixes. 73 74 = 1.2 = 75 * New API compatibility. Speed improvements. 76 71 77 == Upgrade Notice == 72 78 73 79 = 1.0 = 74 80 This is the initial release. 81 82 = 1.2 = 83 Much faster. The plugin now caches all results locally and no longer has any major effect on load time. Also, full support for UTF-8.
Note: See TracChangeset
for help on using the changeset viewer.