1
0

Add the functionality to add a photo remotely. Refactor the url_connection class to handle multipar/form-data posts.

This commit is contained in:
Tim Almdal 2009-12-22 12:31:15 -08:00
parent 7451323165
commit 44c441a33a
7 changed files with 106 additions and 52 deletions

View File

@ -43,9 +43,9 @@ class G3_Client_Controller extends Template_Controller {
try { try {
$token = G3Remote::instance()->get_access_token($post["user"], $post["password"]); $token = G3Remote::instance()->get_access_token($post["user"], $post["password"]);
Session::instance()->set("g3_client_access_token", $token); Session::instance()->set("g3_client_access_token", $token);
$resource = G3Remote::instance()->get_resource("gallery"); $response = G3Remote::instance()->get_resource("gallery");
$valid = true; $valid = true;
$content = $this->_get_main_view($resource); $content = $this->_get_main_view($response->resource);
} catch (Exception $e) { } catch (Exception $e) {
Kohana_Log::add("error", Kohana_Exception::text($e)); Kohana_Log::add("error", Kohana_Exception::text($e));
$valid = false; $valid = false;

View File

@ -22,7 +22,7 @@ class G3_Handlers_Controller extends Controller {
$path = $this->input->get("path"); $path = $this->input->get("path");
if ($_POST) { if ($_POST) {
try { try {
unset($_POST["submit"]); unset($_POST["do_edit"]);
$result = G3Remote::instance()->update_resource("gallery/$path", $_POST); $result = G3Remote::instance()->update_resource("gallery/$path", $_POST);
if ($result->status == "OK") { if ($result->status == "OK") {
$form = null; $form = null;
@ -53,12 +53,25 @@ class G3_Handlers_Controller extends Controller {
public function add($type) { public function add($type) {
$path = $this->input->get("path"); $path = $this->input->get("path");
if ($_POST) { if ($_POST) {
unset($_POST["submit"]); try {
$_POST["name"] = empty($_POST["name"]) ? $_POST["title"] : $_POST["name"]; unset($_POST["do_edit"]);
$_POST["name"] = g3_client::sanitize_filename($_POST["name"]); $data = array(
$_POST["slug"] = empty($_POST["slug"]) ? $_POST["title"] : $_POST["slug"]; "title" => $_POST["title"],
$_POST["slug"] = g3_client::sanitize_slug($_POST["slug"]); "name" => g3_client::sanitize_title($_POST["name"], $_POST["title"]),
$result = G3Remote::instance()->add_resource("gallery/$path/{$_POST['slug']}", $_POST); "slug" => g3_client::sanitize_title($_POST["slug"], $_POST["title"]),
"description" => $_POST["description"]);
if ($_FILES) {
if (empty($_FILES["image"]["error"])) {
unset($_FILES["image"]["error"]);
$data["image"] = (object)$_FILES["image"];
} else {
throw new Exception("File upload failed for reason: {$_FILES['image']['error']}");
}
}
$path = !empty($path) ? $path . "/" : $path;
$result = G3Remote::instance()->add_resource("gallery/$path{$data['slug']}", $data);
if ($result->status == "OK") { if ($result->status == "OK") {
$form = null; $form = null;
$result = "success"; $result = "success";
@ -71,6 +84,12 @@ class G3_Handlers_Controller extends Controller {
} }
$result = "display"; $result = "display";
} }
} catch (Exception $e) {
Kohana_Log::add("error", (string)$e);
$form = g3_client::get_form($type, true, $path, (object)$_POST);
$form->errors["form_error"] = $e->getMessage();
$result = "error";
}
} else { } else {
$form = g3_client::get_form($type, true, $path); $form = g3_client::get_form($type, true, $path);
$result = "display"; $result = "display";

View File

@ -28,8 +28,8 @@ class g3_client_Core {
// @todo add sort column sort order fields // @todo add sort column sort order fields
$form->errors = array("title" => "", "name" => "", "description" => "", "slug" => ""); $form->errors = array("title" => "", "name" => "", "description" => "", "slug" => "");
if ($type != "album" && $add_form) { if ($type != "album" && $add_form) {
$form->form["image_file"] = (object)array("value" => "", "label" => "Image File"); $form->form["image"] = (object)array("value" => "", "label" => "Image File");
$form->errors["image_file"] = ""; $form->errors["image"] = "";
} }
if (empty($path) && !$add_form) { if (empty($path) && !$add_form) {
@ -52,6 +52,7 @@ class g3_client_Core {
$json->form = new View("edit.html"); $json->form = new View("edit.html");
$json->form->title = ($form->adding ? "Add " : "Update ") . ucwords($type); $json->form->title = ($form->adding ? "Add " : "Update ") . ucwords($type);
$json->form->url = $form->adding ? "add" : "edit"; $json->form->url = $form->adding ? "add" : "edit";
$json->form->button_text = $form->adding ? "Add" : "Update";
$json->form->path = $path; $json->form->path = $path;
$json->form->type = $type; $json->form->type = $type;
$json->form->form = (object)$form->form; $json->form->form = (object)$form->form;
@ -70,19 +71,8 @@ class g3_client_Core {
* @param string $filename * @param string $filename
* @return string sanitized filename * @return string sanitized filename
*/ */
static function sanitize_filename($filename) { static function sanitize_title($field, $title) {
$filename = empty($filename) ? $title : $filename; $result = preg_replace("/[^A-Za-z0-9-_]+/", "-", empty($field) ? $title : $field);
$filename = strtr($filename, " ", "_");
$filename = preg_replace("/\..*?$/", "", $filename);
return preg_replace("/ +/", " ", $filename);
}
/**
* Santize the input url into something safe we can us as the url component.
* @param string $filename
*/
static function sanitize_slug($uri) {
$result = preg_replace("/[^A-Za-z0-9-_]+/", "-", $uri);
return trim($result, "-"); return trim($result, "-");
} }
} }

View File

@ -19,20 +19,66 @@
*/ */
class url_connection { class url_connection {
static function post($url, $post_data_array, $extra_headers=array()) { static function post($url, $post_data_array, $extra_headers=array()) {
$_data_raw = self::_encode_data($post_data_array, $extra_headers); //$_data_raw = self::_encode_data($post_data_array, $extra_headers);
$boundary = str_repeat("-", 9) . md5(microtime());
$boundary_length = strlen($boundary);
$extra_headers['Content-Type'] = 'application/x-www-form-urlencoded'; $extra_headers['Content-Type'] = "multipart/form-data; boundary=$boundary";
$extra_headers['Content-Length'] = strlen($_data_raw); $length = 0;
$fields = array();
foreach ($post_data_array as $field => $value) {
$fields[$field] = array();
if (is_string($value)) {
$fields[$field]["disposition"] = "Content-Disposition: form-data; name=\"$field\"\r\n\r\n";
$fields[$field]["type"] = "";
$fields[$field]["value"] = "$value\r\n";
} else {
$fields[$field]["disposition"] =
"Content-Disposition: form-data; name=\"$field\"; filename=\"{$value->name}\"\r\n";
$fields[$field]["type"] = "Content-Type: {$value->type}\r\n\r\n";
$fields[$field]["value"] = "\r\n";
$fields[$field]["local_file"] = $value->tmp_name;
$length += $value->size;
}
$length += strlen($fields[$field]["disposition"]) + strlen($fields[$field]["value"]) +
strlen($fields[$field]["type"]) + $boundary_length + 4;
}
$length += $boundary_length + 6; // boundary terminator and last crlf
$extra_headers['Content-Length'] = $length;
$socket = url_connection::_open_socket($url, 'POST', $extra_headers);
$sent_length = 0;
foreach ($fields as $field => $value) {
$sent_length += fwrite($socket, "--$boundary\r\n");
$sent_length += fwrite($socket, $value["disposition"]);
if (!empty($value["type"])) {
$sent_length += fwrite($socket, $value["type"]);
$file = fopen($value["local_file"], "rb");
while (!feof($file)) {
$buffer = fread($file, 8192);
$sent_length += fwrite($socket, $buffer);
fflush($socket);
}
}
$sent_length += fwrite($socket, $value["value"]);
fflush($socket);
}
$sent_length += fwrite($socket, "--$boundary--\r\n");
fflush($socket);
/* Read the web page into a buffer */ /* Read the web page into a buffer */
return self::do_request($url, 'POST', $extra_headers, $_data_raw); return url_connection::_get_response($socket);
} }
static function get($url, $_data_array=array(), $extra_headers=array()) { static function get($url, $_data_array=array(), $extra_headers=array()) {
$_data_raw = self::_encode_data($_data_array, $extra_headers); $_data_raw = self::_encode_data($_data_array, $extra_headers);
$handle = url_connection::_open_socket("{$url}?$_data_raw", "GET", $extra_headers);
/* Read the web page into a buffer */ /* Read the web page into a buffer */
return self::do_request("{$url}?$_data_raw", "GET", $extra_headers); return url_connection::_get_response($handle);
} }
static function success($response_status) { static function success($response_status) {
@ -60,12 +106,9 @@ class url_connection {
} }
/** /**
* A single request, without following redirects * Open the socket to server
*
* @todo: Handle redirects? If so, only for GET (i.e. not for POST), and use G2's
* WebHelper_simple::_parseLocation logic.
*/ */
static function do_request($url, $method='GET', $headers=array(), $body='') { static function _open_socket($url, $method='GET', $headers=array()) {
/* Convert illegal characters */ /* Convert illegal characters */
$url = str_replace(' ', '%20', $url); $url = str_replace(' ', '%20', $url);
@ -81,18 +124,19 @@ class url_connection {
$header_lines[] = $key . ': ' . $value; $header_lines[] = $key . ': ' . $value;
} }
$success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n%s", $success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n",
$method, $method,
$url_components['uri'], $url_components['uri'],
implode("\r\n", $header_lines), implode("\r\n", $header_lines)));
$body));
if (!$success) {
// Zero bytes written or false was returned
// log "fwrite failed in requestWebPage($url)" . ($success === false ? ' - false' : ''
return array(null, null, null);
}
fflush($handle); fflush($handle);
return $handle;
}
/**
* Read the http response
*/
static function _get_response($handle) {
/* /*
* Read the status line. fgets stops after newlines. The first line is the protocol * Read the status line. fgets stops after newlines. The first line is the protocol
* version followed by a numeric status code and its associated textual phrase. * version followed by a numeric status code and its associated textual phrase.

View File

@ -26,9 +26,9 @@
</li> </li>
<? if ($function == "add_photo"): ?> <? if ($function == "add_photo"): ?>
<li> <li>
<?= form::label("image_file", "Image File:") ?><br/> <?= form::label("image", "Image File:") ?><br/>
<?= form::upload("image_file", $form["image_file"]) ?> <?= form::upload("image", $form["image_file"]) ?>
<?= empty($errors["image_file"]) ? "" : "<span class=\"error\">{$errors["image_file"]}</span>" ?> <?= empty($errors["image"]) ? "" : "<span class=\"error\">{$errors["image"]}</span>" ?>
</li> </li>
<? endif ?> <? endif ?>
<li style="text-align: center"> <li style="text-align: center">

View File

@ -27,11 +27,11 @@
empty($form->slug->readonly) ? "" : "readonly={$form->slug->readonly}") ?> empty($form->slug->readonly) ? "" : "readonly={$form->slug->readonly}") ?>
<?= empty($errors->slug) ? "" : "<span class=\"error\">{$errors->slug}</span>" ?> <?= empty($errors->slug) ? "" : "<span class=\"error\">{$errors->slug}</span>" ?>
</li> </li>
<? if (!empty($form->image_file)): ?> <? if (!empty($form->image)): ?>
<li> <li>
<?= form::label("image_file", "{$form->image_file->label}:") ?><br/> <?= form::label("image", "{$form->image->label}:") ?><br/>
<?= form::upload("image_file") ?> <?= form::upload("image") ?>
<?= empty($errors->image_file) ? "" : "<span class=\"error\">{$errors->image_file}</span>" ?> <?= empty($errors->image) ? "" : "<span class=\"error\">{$errors->image}</span>" ?>
</li> </li>
<? endif ?> <? endif ?>
<? if (!empty($errors->form_error)): ?> <? if (!empty($errors->form_error)): ?>
@ -40,7 +40,7 @@
</li> </li>
<? endif ?> <? endif ?>
<li style="text-align: center"> <li style="text-align: center">
<?= form::submit("submit", "Update") ?> <?= form::submit("do_edit", $button_text) ?>
<?= form::input(array('type'=>'reset','name'=>'reset'), "Reset") ?> <?= form::input(array('type'=>'reset','name'=>'reset'), "Reset") ?>
</li> </li>
</ul> </ul>

View File

@ -192,12 +192,13 @@
$.getJSON("/g3_client/index.php/" + dialog, {path: resource_path}, function(data) { $.getJSON("/g3_client/index.php/" + dialog, {path: resource_path}, function(data) {
$("#g-dialog").html(data.form); $("#g-dialog").html(data.form);
$("#g-dialog").dialog("open");
if ($("#g-dialog fieldset legend").length) { if ($("#g-dialog fieldset legend").length) {
$("#g-dialog").dialog('option', 'title', $("#g-dialog fieldset legend:eq(0)").html()); $("#g-dialog").dialog('option', 'title', $("#g-dialog fieldset legend:eq(0)").html());
} }
_ajaxifyDialog(); _ajaxifyDialog();
$("#g-dialog").dialog("open");
}); });
} }
@ -206,7 +207,7 @@
$("#g-dialog form").ajaxForm({ $("#g-dialog form").ajaxForm({
dataType: "json", dataType: "json",
beforeSubmit: function(formData, form, options) { beforeSubmit: function(formData, form, options) {
form.find(":submit") form.find(":submit, :reset")
.addClass("ui-state-disabled") .addClass("ui-state-disabled")
.attr("disabled", "disabled"); .attr("disabled", "disabled");
return true; return true;