Changeset 1965463
- Timestamp:
- 10/29/2018 10:39:20 PM (7 years ago)
- Location:
- easycoder/trunk
- Files:
-
- 1 added
- 6 edited
-
easycoder-min.js (added)
-
easycoder.js (modified) (3 diffs)
-
easycoder.php (modified) (2 diffs)
-
plugin-browser.js (modified) (4 diffs)
-
plugin-json.js (modified) (9 diffs)
-
readme.txt (modified) (1 diff)
-
rest.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
easycoder/trunk/easycoder.js
r1963561 r1965463 2007 2007 content: '' 2008 2008 }; 2009 case 'newline': 2010 return { 2011 type: 'constant', 2012 numeric: false, 2013 content: `\n` 2014 }; 2009 2015 case 'encode': 2010 2016 return { … … 2348 2354 script.src = 'plugins.js'; 2349 2355 } else { 2350 script.src = '/rest//plugins/' + plugins.join(); 2356 // Call rest.php to catenate all the plugins 2357 const loc = window.location.href; 2358 const doubleSlash = loc.indexOf('//'); 2359 const siteEnd = loc.indexOf('/', doubleSlash + 2); 2360 const site = loc.substr(0, siteEnd); 2361 script.src = site + '/wp-content/plugins/easycoder/rest.php/plugins/' + plugins.join(); 2351 2362 } 2352 2363 head.appendChild(script); … … 2422 2433 while (queue.length > 0) { 2423 2434 program.pc = queue.shift(); 2435 program.watchdog = 0; 2424 2436 while (true) { 2437 if (program.watchdog > 1000000) { 2438 program.lino = program[program.pc].lino; 2439 program.reportError(new Error('Program runaway intercepted.\nHave you forgotten to increment a loop counter?'), program.source); 2440 break; 2441 } 2442 program.watchdog++; 2425 2443 const domain = program[program.pc].domain; 2426 2444 // console.log('Run ' + program.pc + ' ' + domain + ':' + program[program.pc].keyword); -
easycoder/trunk/easycoder.php
r1963561 r1965463 4 4 * Plugin URI: https://easycoder.software 5 5 * Description: Control the appearance and behavior of your posts and pages by embedding simple English-like scripts, without the need to learn JavaScript. 6 * Version: 2.1. 26 * Version: 2.1.3 7 7 * Author: EasyCoder Software 8 8 * Author URI: https://easycoder.software … … 14 14 } 15 15 16 function easycoder_activation_hook() {17 // Get the URI this was called with, e.g. "https://mysite.com/wp-admin/plugins.php?..."18 $here = $_SERVER['SCRIPT_URI'];19 // Reduce it to "http://mysite.com/"20 $site = substr($here, 0, strrpos($here, 'wp-'));21 // Build the URI of my "rest.php"22 $restURI = $site.'wp-content/plugins/easycoder/rest.php';23 // Build the path to back up to the wp- folder if necessary24 $backup = '';25 // Find where we are now, e.g. "/home/myuser/mysite.com/wp-admin/..."26 $current = getcwd();27 while (true) {28 // Get the last item; the name of the current directory29 $slash = strrpos($current, '/');30 // Something went wrong, so abandon this31 if ($slash < 0) break;32 $name = substr($current, $slash + 1);33 // If it starts with "wp-" we're done34 if (strpos($name, 'wp-') === 0) {35 break;36 }37 // No, so back up38 $backup .= '../';39 $current = substr($current, 0, $slash);40 }41 // Get the EC template file using relative addressing42 $text = file_get_contents($backup . '../wp-content/plugins/easycoder/easycoder-template.js');43 // Replace the "/rest/" template variables44 $text = str_replace('/rest/', $restURI, $text);45 // Write it back as the "-min" file46 file_put_contents('../wp-content/plugins/easycoder/easycoder-min.js', $text);47 }48 49 register_activation_hook( __FILE__, 'easycoder_activation_hook' );50 51 /**52 * This function runs when WordPress completes its upgrade process53 * @param $upgrader_object Array54 * @param $options Array55 */56 function wp_upe_upgrade_completed( $upgrader_object, $options ) {57 easycoder_activation_hook();58 }59 add_action( 'upgrader_process_complete', 'wp_upe_upgrade_completed', 10, 2 );60 61 16 // The EasyCoder library 62 17 function easycoder_enqueue_script() { 63 18 wp_enqueue_script('easycoder_script', 64 plugin_dir_url( __FILE__ ) . 'easycoder-min.js', array(), '2.1. 2');19 plugin_dir_url( __FILE__ ) . 'easycoder-min.js', array(), '2.1.3'); 65 20 } 66 21 -
easycoder/trunk/plugin-browser.js
r1963561 r1965463 282 282 }, 283 283 284 Disable: { 285 286 compile: (compiler) => { 287 const lino = compiler.getLino(); 288 const tokens = compiler.getTokens(); 289 compiler.next(); 290 if (compiler.isSymbol()) { 291 const symbol = compiler.getToken(); 292 compiler.next(); 293 compiler.addCommand({ 294 domain: 'browser', 295 keyword: 'disable', 296 lino, 297 symbol 298 }); 299 return true; 300 } 301 compiler.addWarning(`Unrecognised syntax in 'disable'`); 302 return false; 303 }, 304 305 run: (program) => { 306 const command = program[program.pc]; 307 const symbol = program.getSymbolRecord(command.symbol); 308 const target = document.getElementById(symbol.value[symbol.index].content); 309 target.disabled = 'true'; 310 return command.pc + 1; 311 } 312 }, 313 284 314 DIV: { 285 315 … … 291 321 run: (program) => { 292 322 return program[program.pc].pc + 1; 323 } 324 }, 325 326 Enable: { 327 328 compile: (compiler) => { 329 const lino = compiler.getLino(); 330 const tokens = compiler.getTokens(); 331 compiler.next(); 332 if (compiler.isSymbol()) { 333 const symbol = compiler.getToken(); 334 compiler.next(); 335 compiler.addCommand({ 336 domain: 'browser', 337 keyword: 'enable', 338 lino, 339 symbol 340 }); 341 return true; 342 } 343 compiler.addWarning(`Unrecognised syntax in 'enable'`); 344 return false; 345 }, 346 347 run: (program) => { 348 const command = program[program.pc]; 349 const symbol = program.getSymbolRecord(command.symbol); 350 const target = document.getElementById(symbol.value[symbol.index].content); 351 target.disabled = false; 352 return command.pc + 1; 293 353 } 294 354 }, … … 1114 1174 case 'div': 1115 1175 return EasyCoder_Plugin.DIV; 1176 case 'disable': 1177 return EasyCoder_Plugin.Disable; 1178 case 'div': 1179 return EasyCoder_Plugin.DIV; 1180 case 'enable': 1181 return EasyCoder_Plugin.Enable; 1116 1182 case 'header': 1117 1183 case 'h1': … … 1289 1355 element = symbolRecord.value[symbolRecord.index].content; 1290 1356 target = document.getElementById(element); 1357 var content = target.innerHTML.split(`\n`).join(``); 1358 switch (symbolRecord.keyword) { 1359 case 'input': 1360 content = target.value; 1361 break; 1362 } 1291 1363 return { 1292 1364 type: 'constant', 1293 1365 numeric: false, 1294 content : target.innerHTML1366 content 1295 1367 }; 1296 1368 break; -
easycoder/trunk/plugin-json.js
r1963561 r1965463 10 10 case 'get': 11 11 compiler.next(); 12 if (compiler.tokenIs(' item')) {12 if (compiler.tokenIs('property')) { 13 13 compiler.next(); 14 14 const item = compiler.getValue(); … … 28 28 keyword: 'json', 29 29 lino, 30 request: 'get Item',30 request: 'getProperty', 31 31 target: targetRecord.name, 32 32 item, … … 74 74 case 'set': 75 75 compiler.next(); 76 if (compiler.tokenIs(' item')) {76 if (compiler.tokenIs('property')) { 77 77 compiler.next(); 78 78 const name = compiler.getValue(); … … 90 90 keyword: 'json', 91 91 lino, 92 request: 'set Item',92 request: 'setProperty', 93 93 target: targetRecord.name, 94 94 name, … … 178 178 var targetRecord; 179 179 switch (command.request) { 180 case 'get Item':180 case 'getProperty': 181 181 sourceRecord = program.getSymbolRecord(command.source); 182 182 const itemData = JSON.parse(sourceRecord.value[sourceRecord.index].content); … … 213 213 }; 214 214 break; 215 case 'set Item':215 case 'setProperty': 216 216 targetRecord = program.getSymbolRecord(command.target); 217 217 const targetValue = targetRecord.value[targetRecord.index]; 218 218 const targetItem = JSON.parse(program.getValue(targetValue)); 219 219 const itemName = program.getValue(command.name); 220 const itemValue = program.getValue(command.value) ;220 const itemValue = program.getValue(command.value).split(`"`).join(`\\"`).split(`'`).join(`''`); 221 221 targetItem[itemName] = itemValue; 222 222 targetRecord.value[targetRecord.index] = { … … 297 297 case 'post': 298 298 compiler.next(); 299 var name = null;300 299 var value = null; 301 300 if (compiler.tokenIs('to')) { … … 310 309 } 311 310 const url = compiler.getValue(); 312 if (compiler.tokenIs('as')) { 313 compiler.next(); 314 name = compiler.getValue(); 315 } 316 compiler.addCommand({ 317 domain: 'json', 318 keyword: 'rest', 319 lino, 320 request: 'post', 321 value, 322 name, 323 url 324 }); 325 return true; 311 compiler.addCommand({ 312 domain: 'json', 313 keyword: 'rest', 314 lino, 315 request: 'post', 316 value, 317 url 318 }); 319 return true; 320 break; 326 321 } 327 322 return false; … … 370 365 break; 371 366 case 'post': 372 const name = encodeURI(program.getValue(command.name));373 367 const value = encodeURI(program.getValue(command.value)); 374 368 xhttp.open('POST', url, true); 375 369 xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 376 // console.log(`Send ' name=${name}&value=${value}' to\n${url}`);377 xhttp.send(` name=${name}&value=${value}`);370 // console.log(`Send 'value=${value}'\nto ${url}`); 371 xhttp.send(`value=${value}`); 378 372 break; 379 373 } -
easycoder/trunk/readme.txt
r1963561 r1965463 39 39 == Documentation == 40 40 41 Comprehensive documentation is available at [https://easycoder.software](https://easycoder.software/documentation).41 Comprehensive documentation is available at our [documentation](https://easycoder.software/documentation)page. 42 42 43 43 == Examples == 44 44 45 A range of example scripts can be seen at [https://easycoder.software](https://easycoder.software/examples). 45 A range of example scripts can be seen at our [examples](https://easycoder.software/examples) page. 46 47 == Learning resources == 48 49 Tutorials and a workshop exercise are available at [EasyCoder Software](https://easycoder.software). 46 50 47 51 == Changelog == 52 53 = 2.1.3 29-oct-2018 = 54 * Revised REST functionality. 48 55 49 56 = 2.1.2 26-oct-2018 = -
easycoder/trunk/rest.php
r1963126 r1965463 1 1 <?php 2 // REST server 3 4 // Set the error and exception handlers. 5 set_error_handler("my_error_handler"); 6 set_exception_handler('defaultException'); 2 // REST server 7 3 8 4 $request = explode("/", substr($_SERVER['PATH_INFO'], 1)); 9 switch ($_SERVER['REQUEST_METHOD']) { 5 $command = $request[0]; 6 if ($command == 'plugins') { 7 $names = explode(',', str_replace('~', '/', $request[1])); 8 $response = ''; 9 for ($index = 0; $index < count($names); $index++) { 10 $name = $names[$index]; 11 if ($name != 'http' && strpos($name, 'http') === 0) { 12 $text = file_get_contents($name); 13 } else { 14 $text = file_get_contents("plugin-$name.js"); 15 } 16 $response .= str_replace("EasyCoder_Plugin", "EasyCoder_$index", $text); 17 } 18 print $response; 19 exit; 20 } 21 22 $props = array(); 23 $file = fopen('../../../../ec-rest.txt', "r"); 24 if (!file) { 25 http_response_code(404); 26 die('Could not read properties file.'); 27 } 28 $key = null; 29 while (!feof($file)) 30 { 31 $ss = trim(fgets($file)); 32 if (!$ss || substr($ss, 0, 1) == "#") continue; 33 $ss = explode("=", $ss, 2); 34 if (isset($ss[1])) 35 { 36 $key = $ss[0]; 37 $props[$key] = $ss[1]; 38 } 39 } 40 fclose($file); 41 42 $conn = mysqli_connect($props['sqlhost'], $props['sqluser'], 43 $props['sqlpassword'], $props['sqldatabase']); 44 if (!$conn) 45 { 46 http_response_code(404); 47 die("Failed to connect to MySQL: " . mysqli_connect_error()); 48 } 49 mysqli_set_charset($link,'utf8'); 50 51 if (count($request) < 2) { 52 http_response_code(400); 53 print "{\"message\":\"Incomplete REST query.\"}"; 54 exit; 55 } 56 57 header('Access-Control-Allow-Origin: *'); 58 header('Content-Type: application/json, text/html'); 59 header('Access-Control-Allow-Headers: Content-Type'); 60 header('Access-Control-Allow-Methods: GET, POST'); 61 62 switch ($command) { 63 case 'data': 64 $table = $props['sqldatatable']; 65 break; 66 case 'articles': 67 $table = $props['sqlarticlestable']; 68 break; 69 default: 70 http_response_code(404); 71 print "{\"message\":\"Unknown identifier '$command'.\"}"; 72 exit; 73 } 74 $method = $_SERVER['REQUEST_METHOD']; 75 switch ($method) { 76 10 77 case 'GET': 11 if ($request[0] == 'plugins') { 12 $names = explode(',', str_replace('~', '/', $request[1])); 13 $response = ''; 14 for ($index = 0; $index < count($names); $index++) { 15 $name = $names[$index]; 16 if ($name != 'http' && strpos($name, 'http') === 0) { 17 $text = file_get_contents($name); 78 get($props, $conn, $table, $request); 79 break; 80 81 case 'POST': 82 post($props, $conn, $table, $request); 83 break; 84 85 default: 86 http_response_code(400); 87 break; 88 } 89 mysqli_close(); 90 exit(); 91 92 ///////////////////////////////////////////////////////////////////////// 93 // GET 94 function get($props, $conn, $table, $request) { 95 $action = $request[1]; 96 switch ($action) { 97 case 'count': 98 // Return the number of items in the table 99 $result = $conn->query("SELECT id from $table"); 100 //print "{\"count\":".mysqli_num_rows($result)."}"; 101 print mysqli_num_rows($result); 102 break; 103 case 'list': 104 switch (count($request)) { 105 case 3: 106 $offset = 0; 107 $count = $request[2]; 108 break; 109 case 4: 110 $offset = $request[2]; 111 $count = $request[3]; 112 break; 113 default: 114 $offset = 0; 115 $count = 10; 116 break; 117 } 118 $result = $conn->query("SELECT id FROM $table LIMIT $offset, $count"); 119 $response = '['; 120 while ($row = mysqli_fetch_object($result)) { 121 if ($response != '[') { 122 $response .= ','; 123 } 124 $response .= $row->id; 125 } 126 $response .= ']'; 127 print $response; 128 break; 129 case 'id': 130 if (count($request) < 3) { 131 http_response_code(400); 132 print "{\"message\":\"Incomplete REST query.\"}"; 133 exit; 134 } 135 $id = $request[2]; 136 $result = $conn->query("SELECT value FROM $table WHERE id='$id'"); 137 if ($row = mysqli_fetch_object($result)) { 138 print $row->value; 139 } else { 140 http_response_code(404); 141 print "{\"message\":\"Cannot get item id '$id' as it does not exist.\"}"; 142 } 143 break; 144 case 'name': 145 if (count($request) < 3) { 146 http_response_code(400); 147 print "{\"message\":\"Incomplete REST query.\"}"; 148 exit; 149 } 150 $name = $request[2]; 151 $result = $conn->query("SELECT value FROM $table WHERE name='$name'"); 152 if ($row = mysqli_fetch_object($result)) { 153 print $row->value; 154 } else { 155 http_response_code(404); 156 print "{\"message\":\"Cannot get item name '$name' as it does not exist.\"}"; 157 } 158 break; 159 } 160 } 161 162 ///////////////////////////////////////////////////////////////////////// 163 // POST 164 function post($props, $conn, $table, $request) { 165 $ts = time(); 166 $action = $request[1]; 167 switch ($action) { 168 case 'set': 169 if (count($request) > 3) { 170 switch ($request[2]) { 171 case 'id': 172 $value = $_POST['value']; 173 $id = $request[3]; 174 // See if there's an item with this id 175 $result = $conn->query("SELECT id FROM $table WHERE id=$id"); 176 if (mysqli_fetch_object($result)) { 177 // It exists, so update it 178 query($conn, "UPDATE $table SET value='$value',ts=$ts WHERE id=$id"); 179 } else { 180 // Not found 181 http_response_code(404); 182 print "{\"message\":\"Cannot set item $id as it does not exist.\"}"; 183 } 184 break; 185 case 'name': 186 $value = urldecode($_POST['value']); 187 $name = urldecode($request[3]); 188 // See if there's an item with this name 189 $result = $conn->query("SELECT id FROM $table WHERE name='$name'"); 190 if (mysqli_fetch_object($result)) { 191 // It exists, so update it 192 query($conn, "UPDATE $table SET value='$value',ts=$ts WHERE name='$name'"); 193 } else { 194 // Add a new item 195 query($conn, "INSERT INTO $table (name,value,ts) VALUES ('$name','$value','$ts')"); 196 http_response_code(201); 197 } 198 break; 199 default: 200 http_response_code(400); 201 print "{\"message\":\"Value '".$request[2]."' should be 'id' or 'name'.\"}"; 202 break; 203 } 204 } else { 205 http_response_code(400); 206 print "{\"message\":\"Incomplete REST query.\"}"; 207 } 208 break; 209 case 'delete': 210 if (count($request) > 2) { 211 $item = $request[2]; 212 if (is_int($item)) { 213 // Delete the requested id 214 query($conn, "DELETE FROM $table WHERE id=$id"); 18 215 } else { 19 $text = file_get_contents("plugin-$name.js"); 20 } 21 $response .= str_replace("EasyCoder_Plugin", "EasyCoder_$index", $text); 22 } 23 print $response; 24 } 25 break; 26 } 27 28 //////////////////////////////////////////////////////////////////////////// 29 // Our custom error handler. 30 function my_error_handler ($errno, $errstr, $errfile, $errline, $errcontent) 31 { 32 echo "An Error Occured!\n"; 33 echo " File: $errfile\n"; 34 echo " $errline\n"; 35 echo " $errno\n"; 36 echo " $errstr\n"; 37 38 exit; 39 } 40 41 //////////////////////////////////////////////////////////////////////////// 42 // Catch any exceptions that weren't handled anywhere else. 43 function defaultException($e) 44 { 45 header('HTTP/1.x 555 Program Error'); 46 print $e->showExceptionInfo(TRUE); 47 exit; 48 } 216 // Delete the named item 217 query($conn, "DELETE FROM $table WHERE name='".urldecode($item)."'"); 218 } 219 } 220 break; 221 case 'rename': 222 $value = urldecode($_POST['value']); 223 $id = $_POST['id']; 224 if (!$id && count($request) > 2) { 225 $id = $request[2]; 226 } 227 if ($id) { 228 query($conn, "UPDATE $table SET name='$name',value='$value' WHERE id=$id"); 229 } else { 230 $name = urldecode($_POST['name']); 231 $newname = urldecode($_POST['newname']); 232 // See if there's a data item with the new name 233 $result = $conn->query("SELECT id FROM $table WHERE name='$newname'"); 234 if ($row = mysqli_fetch_object($result)) { 235 // Conflict 236 http_response_code(409); 237 print "{\"message\":\"Cannot rename item '$name' to '$newname' as it already exists.\"}"; 238 } else { 239 // See if there's a data item with this name 240 $result = $conn->query("SELECT id FROM $table WHERE name='$name'"); 241 if ($row = mysqli_fetch_object($result)) { 242 // There's a data item to rename 243 $id = $row->id; 244 query($conn, "UPDATE $table SET name='$newname',value='$value' WHERE id=$id"); 245 } else { 246 // Not found 247 http_response_code(404); 248 print "{\"message\":\"Cannot rename item '$name' as it does not exist.\"}"; 249 } 250 } 251 } 252 break; 253 case 'truncate': 254 query($conn, "TRUNCATE $table"); 255 break; 256 default: 257 http_response_code(404); 258 print "{\"message\":\"Unrecognised action '$action' requested.\"}"; 259 break; 260 } 261 } 262 263 ///////////////////////////////////////////////////////////////////////// 264 // Do an SQL query 265 function query($conn, $sql) 266 { 267 $result = mysqli_query($conn, $sql); 268 if (!$result) { 269 http_response_code(404); 270 die('Error: '.mysqli_error($conn)); 271 } 272 mysqli_free_result($result); 273 return $result; 274 } 49 275 ?>
Note: See TracChangeset
for help on using the changeset viewer.