private static function insert_log_row($consumer_key, $cache_internal_id, $user_internal_id, $logtype, $when, $formatted_comment, $text_html, $needs_maintenance2) { if (Settings::get('OC_BRANCH') == 'oc.de') { $needs_maintenance_field_SQL = ', needs_maintenance'; if ($needs_maintenance2 == 'true') { $needs_maintenance_SQL = ',2'; } else { if ($needs_maintenance2 == 'false') { $needs_maintenance_SQL = ',1'; } else { // 'null' $needs_maintenance_SQL = ',0'; } } } else { $needs_maintenance_field_SQL = ''; $needs_maintenance_SQL = ''; } $log_uuid = Okapi::create_uuid(); Db::execute("\n insert into cache_logs (\n uuid, cache_id, user_id, type, date, text, text_html,\n last_modified, date_created, node" . $needs_maintenance_field_SQL . "\n ) values (\n '" . Db::escape_string($log_uuid) . "',\n '" . Db::escape_string($cache_internal_id) . "',\n '" . Db::escape_string($user_internal_id) . "',\n '" . Db::escape_string(Okapi::logtypename2id($logtype)) . "',\n from_unixtime('" . Db::escape_string($when) . "'),\n '" . Db::escape_string($formatted_comment) . "',\n '" . Db::escape_string($text_html) . "',\n now(),\n now(),\n '" . Db::escape_string(Settings::get('OC_NODE_ID')) . "'\n " . $needs_maintenance_SQL . "\n );\n "); $log_internal_id = Db::last_insert_id(); # Store additional information on consumer_key which has created this log entry. # (Maybe we'll want to display this somewhen later.) Db::execute("\n insert into okapi_submitted_objects (object_type, object_id, consumer_key)\n values (\n " . Okapi::OBJECT_TYPE_CACHE_LOG . ",\n '" . Db::escape_string($log_internal_id) . "',\n '" . Db::escape_string($consumer_key) . "'\n );\n "); return $log_uuid; }
private static function insert_log_row($consumer_key, $cache_internal_id, $user_internal_id, $logtype, $when, $formatted_comment, $text_html) { $log_uuid = Okapi::create_uuid(); Db::execute("\n insert into cache_logs (uuid, cache_id, user_id, type, date, text, text_html, last_modified, date_created, node)\n values (\n '" . mysql_real_escape_string($log_uuid) . "',\n '" . mysql_real_escape_string($cache_internal_id) . "',\n '" . mysql_real_escape_string($user_internal_id) . "',\n '" . mysql_real_escape_string(Okapi::logtypename2id($logtype)) . "',\n from_unixtime('" . mysql_real_escape_string($when) . "'),\n '" . mysql_real_escape_string($formatted_comment) . "',\n '" . mysql_real_escape_string($text_html) . "',\n now(),\n now(),\n '" . mysql_real_escape_string(Settings::get('OC_NODE_ID')) . "'\n );\n "); $log_internal_id = Db::last_insert_id(); # Store additional information on consumer_key which have created this log entry. # (Maybe we'll want to display this somewhere later.) Db::execute("\n insert into okapi_cache_logs (log_id, consumer_key)\n values (\n '" . mysql_real_escape_string($log_internal_id) . "',\n '" . mysql_real_escape_string($consumer_key) . "'\n );\n "); return $log_uuid; }
/** * Append a new image to a log entry and return the image uuid and position. * Throws CannotPublishException or BadRequest on errors. */ private static function _call(OkapiRequest $request) { require_once 'log_images_common.inc.php'; # Developers! Please notice the fundamental difference between throwing # CannotPublishException and the "standard" BadRequest/InvalidParam # exceptions. You're reading the "_call" method now (see below for # "call"). # validate the 'log_uuid' parameter $log_uuid = $request->get_parameter('log_uuid'); if (!$log_uuid) { throw new ParamMissing('log_uuid'); } $rs = Db::query("\n select id, node, user_id\n from cache_logs\n where uuid = '" . Db::escape_string($log_uuid) . "'"); $row = Db::fetch_assoc($rs); Db::free_result($rs); if (!$row) { throw new InvalidParam('log_uuid', "There is no log entry with uuid '" . $log_uuid . "'."); } if ($row['node'] != Settings::get('OC_NODE_ID')) { throw new Exception("This site's database contains the log entry '{$log_uuid}' which has been" . " imported from another OC node. OKAPI is not prepared for that."); } if ($row['user_id'] != $request->token->user_id) { throw new InvalidParam('log_uuid', "The user of your access token is not the log entry's author."); } $log_internal_id = $row['id']; unset($row); # validate the 'caption', 'is_spoiler' and 'position' parameters $caption = $request->get_parameter('caption'); if (!$caption) { throw new CannotPublishException(sprintf(_("Please enter an image caption."), Okapi::get_normalized_site_name())); } $is_spoiler = $request->get_parameter('is_spoiler'); if ($is_spoiler === null) { $is_spoiler = 'false'; } if (!in_array($is_spoiler, array('true', 'false'))) { throw new InvalidParam('is_spoiler'); } $position = LogImagesCommon::validate_position($request); # validate the 'image' parameter $base64_image = $request->get_parameter('image'); if (!$base64_image) { throw new ParamMissing('image'); } $estimated_decoded_size = strlen($base64_image) / 4 * 3 - 2; if ($estimated_decoded_size > Settings::get('IMAGE_MAX_UPLOAD_SIZE')) { $estimated_decoded_size_MB = round($estimated_decoded_size / 1024 / 1024, 1); $max_upload_size_MB = round(Settings::get('IMAGE_MAX_UPLOAD_SIZE') / 1024 / 1024, 1); throw new CannotPublishException(sprintf(_("Your image file is too large (%s.%s MB); %s accepts a maximum image size of %s.%s MB."), floor($estimated_decoded_size_MB), $estimated_decoded_size_MB * 10 % 10, Okapi::get_normalized_site_name(), floor($max_upload_size_MB), $max_upload_size_MB * 10 % 10)); } $image = base64_decode($base64_image); if (!$image) { throw new InvalidParam('image', "bad base64 encoding"); } try { $image_properties = getimagesizefromstring($image); # can throw if (!$image_properties) { throw new Exception(); } list($width, $height, $image_type) = $image_properties; if (!in_array($image_type, array(IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF))) { # This will happen e.g. for BMP and XBM images, which are supported by GD. throw new Exception(); } } catch (Exception $e) { # Note: There may be *subtypes* which are not accepted by the GD library. # About 1 of 2000 JPEGs at OC.de is not readable by the PHP functions, # though they can be displayed by web browsers. throw new CannotPublishException(sprintf(_("The uploaded image file is broken, or the image type is not accepted by %s. Allowed types are JPEG, PNG and GIF."), Okapi::get_normalized_site_name())); } unset($image_properties); if ($width * $height > self::max_pixels($base64_image)) { # This large image may crash the image processing functions. throw new CannotPublishException(sprintf(_("The uploaded image is too large (%s megapixels), please downscale it."), round($width * $height / 1024 / 1024))); } try { $image = imagecreatefromstring($image); # can throw if (!$image) { throw new Exception(); } } catch (Exception $e) { throw new CannotPublishException(_("The uploaded image file is broken.")); } # Now all supplied paramters are validated. # Do any postprocessing like scaling and rotating $image = self::postprocess_image($base64_image, $image, $image_type, $width, $height); unset($base64_image); # Save the image file. By saving it always from the $image object instead of # the original image data (even if not downscaled or rotated), we # - strip JPEG EXIF information, which is intentional for privacy reasons, # - eliminate any data flaws which have may been in the source files. $image_uuid = Okapi::create_uuid(); $imagepath = Settings::get('IMAGES_DIR') . '/' . $image_uuid; switch ($image_type) { case IMAGETYPE_JPEG: $file_ext = '.jpg'; $quality = Settings::get('JPEG_QUALITY'); $result = imagejpeg($image, $imagepath . $file_ext, $quality); break; case IMAGETYPE_PNG: $file_ext = '.png'; $result = imagepng($image, $imagepath . $file_ext); break; case IMAGETYPE_GIF: $file_ext = '.gif'; $result = imagegif($image, $imagepath . $file_ext); break; default: $file_ext = '.???'; $result = false; } if (!$result) { throw new Exception("could not save image file '" . $imagepath . $file_ext . "'"); } # insert image into database try { $position = self::db_insert_image($request->consumer->key, $request->token->user_id, $log_internal_id, $image_uuid, $position, $caption, $is_spoiler, $file_ext); } catch (Exception $e) { # TODO: Proper handling of nested exception if the unlink() fails # (which is very unlikely, and will just add a bit more of garbage # to that which is already present in the images directory). try { unlink($imagepath . $file_ext); } catch (Exception $e2) { } throw $e; } return array($image_uuid, $position); }