From 7e87cc73281edd256a984e73f290efea30cc57f9 Mon Sep 17 00:00:00 2001 From: Lucas Schmoeller da Silva Date: Fri, 27 Dec 2013 18:02:06 -0200 Subject: [PATCH] #41 Implementando cadastro de foto para pessoa/aluno --- ieducar/configuration/ieducar.ini | 5 +++++ ieducar/intranet/S3.php | 911 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ieducar/intranet/atendidos_cad.php | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ieducar/intranet/atendidos_det.php | 11 ++++++++++- ieducar/intranet/educar_aluno_det.php | 12 +++++++++++- ieducar/intranet/image_check.php | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ieducar/intranet/s3_config.php | 17 +++++++++++++++++ 7 files changed, 1187 insertions(+), 2 deletions(-) create mode 100644 ieducar/intranet/S3.php create mode 100644 ieducar/intranet/image_check.php create mode 100644 ieducar/intranet/s3_config.php diff --git a/ieducar/configuration/ieducar.ini b/ieducar/configuration/ieducar.ini index 371ac31..a96bb21 100644 --- a/ieducar/configuration/ieducar.ini +++ b/ieducar/configuration/ieducar.ini @@ -61,6 +61,11 @@ app.database.port = 5433 ; Define uma url para redirecionar todas as requisições; ; app.routes.redirect_to = /intranet/manutencao.php +; Configurações do armazenamento de imagem amazon s3 +;app.aws.bucketname = nome do bucket +;app.aws.awsacesskey = chave +;app.aws.awssecretkey = chave secreta + ; Configurações de template ; Os caminhos de diretórios devem sempre ser relativos a intranet/ app.template.vars.instituicao = i-Educar diff --git a/ieducar/intranet/S3.php b/ieducar/intranet/S3.php new file mode 100644 index 0000000..a634cb1 --- /dev/null +++ b/ieducar/intranet/S3.php @@ -0,0 +1,911 @@ +getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + $results = array(); //var_dump($rest->body); + if (!isset($rest->body->Buckets)) return $results; + + if ($detailed) { + if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) + $results['owner'] = array( + 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID + ); + $results['buckets'] = array(); + foreach ($rest->body->Buckets->Bucket as $b) + $results['buckets'][] = array( + 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate) + ); + } else + foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name; + + return $results; + } + + + /* + * Get contents for a bucket + * + * If maxKeys is null this method will loop through truncated result sets + * + * @param string $bucket Bucket name + * @param string $prefix Prefix + * @param string $marker Marker (last file listed) + * @param string $maxKeys Max keys (maximum number of keys to return) + * @return array | false + */ + public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null) { + $rest = new S3Request('GET', $bucket, ''); + if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix); + if ($marker !== null && $prefix !== '') $rest->setParameter('marker', $marker); + if ($maxKeys !== null && $prefix !== '') $rest->setParameter('max-keys', $maxKeys); + $response = $rest->getResponse(); + if ($response->error === false && $response->code !== 200) + $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status'); + if ($response->error !== false) { + trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING); + return false; + } + + $results = array(); + + $lastMarker = null; + if (isset($response->body, $response->body->Contents)) + foreach ($response->body->Contents as $c) { + $results[(string)$c->Key] = array( + 'name' => (string)$c->Key, + 'time' => strToTime((string)$c->LastModified), + 'size' => (int)$c->Size, + 'hash' => substr((string)$c->ETag, 1, -1) + ); + $lastMarker = (string)$c->Key; + //$response->body->IsTruncated = 'true'; break; + } + + + if (isset($response->body->IsTruncated) && + (string)$response->body->IsTruncated == 'false') return $results; + + // Loop through truncated results if maxKeys isn't specified + if ($maxKeys == null && $lastMarker !== null && (string)$response->body->IsTruncated == 'true') + do { + $rest = new S3Request('GET', $bucket, ''); + if ($prefix !== null) $rest->setParameter('prefix', $prefix); + $rest->setParameter('marker', $lastMarker); + + if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break; + if (isset($response->body, $response->body->Contents)) + foreach ($response->body->Contents as $c) { + $results[(string)$c->Key] = array( + 'name' => (string)$c->Key, + 'time' => strToTime((string)$c->LastModified), + 'size' => (int)$c->Size, + 'hash' => substr((string)$c->ETag, 1, -1) + ); + $lastMarker = (string)$c->Key; + } + } while ($response !== false && (string)$response->body->IsTruncated == 'true'); + + return $results; + } + + + /** + * Put a bucket + * + * @param string $bucket Bucket name + * @param constant $acl ACL flag + * @return boolean + */ + public function putBucket($bucket, $acl = self::ACL_PRIVATE) { + $rest = new S3Request('PUT', $bucket, ''); + $rest->setAmzHeader('x-amz-acl', $acl); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::putBucket({$bucket}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Delete an empty bucket + * + * @param string $bucket Bucket name + * @return boolean + */ + public function deleteBucket($bucket = '') { + $rest = new S3Request('DELETE', $bucket); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 204) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Create input info array for putObject() + * + * @param string $file Input file + * @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own) + * @return array | false + */ + public static function inputFile($file, $md5sum = true) { + if (!file_exists($file) || !is_file($file) || !is_readable($file)) { + trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING); + return false; + } + return array('file' => $file, 'size' => filesize($file), + 'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum : + base64_encode(md5_file($file, true))) : ''); + } + + + /** + * Use a resource for input + * + * @param string $file Input file + * @param integer $bufferSize Input byte size + * @param string $md5sum MD5 hash to send (optional) + * @return array | false + */ + public static function inputResource(&$resource, $bufferSize, $md5sum = '') { + if (!is_resource($resource) || $bufferSize <= 0) { + trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING); + return false; + } + $input = array('size' => $bufferSize, 'md5sum' => $md5sum); + $input['fp'] =& $resource; + return $input; + } + + + /** + * Put an object + * + * @param mixed $input Input data + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Array of x-amz-meta-* headers + * @param string $contentType Content type + * @return boolean + */ + public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) { + if ($input == false) return false; + $rest = new S3Request('PUT', $bucket, $uri); + + if (is_string($input)) $input = array( + 'data' => $input, 'size' => strlen($input), + 'md5sum' => base64_encode(md5($input, true)) + ); + + // Data + if (isset($input['fp'])) + $rest->fp =& $input['fp']; + elseif (isset($input['file'])) + $rest->fp = @fopen($input['file'], 'rb'); + elseif (isset($input['data'])) + $rest->data = $input['data']; + + // Content-Length (required) + if (isset($input['size']) && $input['size'] > 0) + $rest->size = $input['size']; + else { + if (isset($input['file'])) + $rest->size = filesize($input['file']); + elseif (isset($input['data'])) + $rest->size = strlen($input['data']); + } + + // Content-Type + if ($contentType !== null) + $input['type'] = $contentType; + elseif (!isset($input['type']) && isset($input['file'])) + $input['type'] = self::__getMimeType($input['file']); + else + $input['type'] = 'application/octet-stream'; + + // We need to post with the content-length and content-type, MD5 is optional + if ($rest->size > 0 && ($rest->fp !== false || $rest->data !== false)) { + $rest->setHeader('Content-Type', $input['type']); + if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']); + + $rest->setAmzHeader('x-amz-acl', $acl); + foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v); + $rest->getResponse(); + } else + $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters'); + + if ($rest->response->error === false && $rest->response->code !== 200) + $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); + if ($rest->response->error !== false) { + trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Puts an object from a file (legacy function) + * + * @param string $file Input file path + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Array of x-amz-meta-* headers + * @param string $contentType Content type + * @return boolean + */ + public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) { + return self::putObject(S3::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType); + } + + + /** + * Put an object from a string (legacy function) + * + * @param string $string Input data + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param constant $acl ACL constant + * @param array $metaHeaders Array of x-amz-meta-* headers + * @param string $contentType Content type + * @return boolean + */ + public function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') { + return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType); + } + + + /** + * Get an object + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param mixed &$saveTo Filename or resource to write to + * @return mixed + */ + public static function getObject($bucket = '', $uri = '', $saveTo = false) { + $rest = new S3Request('GET', $bucket, $uri); + if ($saveTo !== false) { + if (is_resource($saveTo)) + $rest->fp =& $saveTo; + else + if (($rest->fp = @fopen($saveTo, 'wb')) == false) + $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo); + } + if ($rest->response->error === false) $rest->getResponse(); + + if ($rest->response->error === false && $rest->response->code !== 200) + $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); + if ($rest->response->error !== false) { + trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s", + $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING); + return false; + } + $rest->file = realpath($saveTo); + return $rest->response; + } + + + /** + * Get object information + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param boolean $returnInfo Return response information + * @return mixed | false + */ + public static function getObjectInfo($bucket = '', $uri = '', $returnInfo = true) { + $rest = new S3Request('HEAD', $bucket, $uri); + $rest = $rest->getResponse(); + if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404)) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false; + } + + + /** + * Set logging for a bucket + * + * @param string $bucket Bucket name + * @param string $targetBucket Target bucket (where logs are stored) + * @param string $targetPrefix Log prefix (e,g; domain.com-) + * @return boolean + */ + public static function setBucketLogging($bucket, $targetBucket, $targetPrefix) { + $dom = new DOMDocument; + $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus'); + $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + + $loggingEnabled = $dom->createElement('LoggingEnabled'); + + $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket)); + $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix)); + + // TODO: Add TargetGrants + + $bucketLoggingStatus->appendChild($loggingEnabled); + $dom->appendChild($bucketLoggingStatus); + + $rest = new S3Request('PUT', $bucket, ''); + $rest->setParameter('logging', null); + $rest->data = $dom->saveXML(); + $rest->size = strlen($rest->data); + $rest->setHeader('Content-Type', 'application/xml'); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get logging status for a bucket + * + * This will return false if logging is not enabled. + * Note: To enable logging, you also need to grant write access to the log group + * + * @param string $bucket Bucket name + * @return array | false + */ + public static function getBucketLogging($bucket = '') { + $rest = new S3Request('GET', $bucket, ''); + $rest->setParameter('logging', null); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + if (!isset($rest->body->LoggingEnabled)) return false; // No logging + return array( + 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket, + 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix, + ); + } + + + /** + * Set object or bucket Access Control Policy + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy) + * @return boolean + */ + public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) { + $dom = new DOMDocument; + $dom->formatOutput = true; + $accessControlPolicy = $dom->createElement('AccessControlPolicy'); + $accessControlList = $dom->createElement('AccessControlList'); + + // It seems the owner has to be passed along too + $owner = $dom->createElement('Owner'); + $owner->appendChild($dom->createElement('ID', $acp['owner']['id'])); + $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name'])); + $accessControlPolicy->appendChild($owner); + + foreach ($acp['acl'] as $g) { + $grant = $dom->createElement('Grant'); + $grantee = $dom->createElement('Grantee'); + $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted) + $grantee->setAttribute('xsi:type', 'CanonicalUser'); + $grantee->appendChild($dom->createElement('ID', $g['id'])); + } elseif (isset($g['email'])) { // AmazonCustomerByEmail + $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail'); + $grantee->appendChild($dom->createElement('EmailAddress', $g['email'])); + } elseif ($g['type'] == 'Group') { // Group + $grantee->setAttribute('xsi:type', 'Group'); + $grantee->appendChild($dom->createElement('URI', $g['uri'])); + } + $grant->appendChild($grantee); + $grant->appendChild($dom->createElement('Permission', $g['permission'])); + $accessControlList->appendChild($grant); + } + + $accessControlPolicy->appendChild($accessControlList); + $dom->appendChild($accessControlPolicy); + + $rest = new S3Request('PUT', $bucket, ''); + $rest->setParameter('acl', null); + $rest->data = $dom->saveXML(); + $rest->size = strlen($rest->data); + $rest->setHeader('Content-Type', 'application/xml'); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get object or bucket Access Control Policy + * + * Currently this will trigger an error if there is no ACL on an object (will fix soon) + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @return mixed | false + */ + public static function getAccessControlPolicy($bucket, $uri = '') { + $rest = new S3Request('GET', $bucket, $uri); + $rest->setParameter('acl', null); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 200) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s", + $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + + $acp = array(); + if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) { + $acp['owner'] = array( + 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName + ); + } + if (isset($rest->body->AccessControlList)) { + $acp['acl'] = array(); + foreach ($rest->body->AccessControlList->Grant as $grant) { + foreach ($grant->Grantee as $grantee) { + if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser + $acp['acl'][] = array( + 'type' => 'CanonicalUser', + 'id' => (string)$grantee->ID, + 'name' => (string)$grantee->DisplayName, + 'permission' => (string)$grant->Permission + ); + elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail + $acp['acl'][] = array( + 'type' => 'AmazonCustomerByEmail', + 'email' => (string)$grantee->EmailAddress, + 'permission' => (string)$grant->Permission + ); + elseif (isset($grantee->URI)) // Group + $acp['acl'][] = array( + 'type' => 'Group', + 'uri' => (string)$grantee->URI, + 'permission' => (string)$grant->Permission + ); + else continue; + } + } + } + return $acp; + } + + + /** + * Delete an object + * + * @param string $bucket Bucket name + * @param string $uri Object URI + * @return mixed + */ + public static function deleteObject($bucket = '', $uri = '') { + $rest = new S3Request('DELETE', $bucket, $uri); + $rest = $rest->getResponse(); + if ($rest->error === false && $rest->code !== 204) + $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); + if ($rest->error !== false) { + trigger_error(sprintf("S3::deleteObject(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); + return false; + } + return true; + } + + + /** + * Get MIME type for file + * + * @internal Used to get mime types + * @param string &$file File path + * @return string + */ + public static function __getMimeType(&$file) { + $type = false; + // Fileinfo documentation says fileinfo_open() will use the + // MAGIC env var for the magic file + if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) && + ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) { + if (($type = finfo_file($finfo, $file)) !== false) { + // Remove the charset and grab the last content-type + $type = explode(' ', str_replace('; charset=', ';charset=', $type)); + $type = array_pop($type); + $type = explode(';', $type); + $type = array_shift($type); + } + finfo_close($finfo); + + // If anyone is still using mime_content_type() + } elseif (function_exists('mime_content_type')) + $type = mime_content_type($file); + + if ($type !== false && strlen($type) > 0) return $type; + + // Otherwise do it the old fashioned way + static $exts = array( + 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', + 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon', + 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf', + 'zip' => 'application/zip', 'gz' => 'application/x-gzip', + 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain', + 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html', + 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml', + 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav', + 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', + 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php' + ); + $ext = strToLower(pathInfo($file, PATHINFO_EXTENSION)); + return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream'; + } + + + /** + * Generate the auth string: "AWS AccessKey:Signature" + * + * This uses the hash extension if loaded + * + * @internal Signs the request + * @param string $string String to sign + * @return string + */ + public static function __getSignature($string) { + return 'AWS '.self::$__accessKey.':'.base64_encode(extension_loaded('hash') ? + hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1( + (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) . + pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^ + (str_repeat(chr(0x36), 64))) . $string))))); + } + + +} + +final class S3Request { + private $verb, $bucket, $uri, $resource = '', $parameters = array(), + $amzHeaders = array(), $headers = array( + 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => '' + ); + public $fp = false, $size = 0, $data = false, $response; + + + /** + * Constructor + * + * @param string $verb Verb + * @param string $bucket Bucket name + * @param string $uri Object URI + * @return mixed + */ + function __construct($verb, $bucket = '', $uri = '') { + $this->verb = $verb; + $this->bucket = strtolower($bucket); + $this->uri = $uri !== '' ? '/'.$uri : '/'; + + if ($this->bucket !== '') { + $this->bucket = explode('/', $this->bucket); + $this->resource = '/'.$this->bucket[0].$this->uri; + $this->headers['Host'] = $this->bucket[0].'.s3.amazonaws.com'; + $this->bucket = implode('/', $this->bucket); + } else { + $this->headers['Host'] = 's3.amazonaws.com'; + if (strlen($this->uri) > 1) + $this->resource = '/'.$this->bucket.$this->uri; + else $this->resource = $this->uri; + } + $this->headers['Date'] = gmdate('D, d M Y H:i:s T'); + + $this->response = new STDClass; + $this->response->error = false; + } + + + /** + * Set request parameter + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function setParameter($key, $value) { + $this->parameters[$key] = $value; + } + + + /** + * Set request header + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function setHeader($key, $value) { + $this->headers[$key] = $value; + } + + + /** + * Set x-amz-meta-* header + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function setAmzHeader($key, $value) { + $this->amzHeaders[$key] = $value; + } + + + /** + * Get the S3 response + * + * @return object | false + */ + public function getResponse() { + $query = ''; + if (sizeof($this->parameters) > 0) { + $query = substr($this->uri, -1) !== '?' ? '?' : '&'; + foreach ($this->parameters as $var => $value) + if ($value == null || $value == '') $query .= $var.'&'; + else $query .= $var.'='.$value.'&'; + $query = substr($query, 0, -1); + $this->uri .= $query; + if (isset($this->parameters['acl']) || !isset($this->parameters['logging'])) + $this->resource .= $query; + } + $url = (extension_loaded('openssl')?'https://':'http://').$this->headers['Host'].$this->uri; + //var_dump($this->bucket, $this->uri, $this->resource, $url); + + + // Basic setup + $curl = curl_init(); + curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php'); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($curl, CURLOPT_URL, $url); + + // Headers + $headers = array(); $amz = array(); + foreach ($this->amzHeaders as $header => $value) + if (strlen($value) > 0) $headers[] = $header.': '.$value; + foreach ($this->headers as $header => $value) + if (strlen($value) > 0) $headers[] = $header.': '.$value; + foreach ($this->amzHeaders as $header => $value) + if (strlen($value) > 0) $amz[] = strToLower($header).':'.$value; + $amz = (sizeof($amz) > 0) ? "\n".implode("\n", $amz) : ''; + + // Authorization string + $headers[] = 'Authorization: ' . S3::__getSignature( + $this->verb."\n". + $this->headers['Content-MD5']."\n". + $this->headers['Content-Type']."\n". + $this->headers['Date'].$amz."\n".$this->resource + ); + + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_HEADER, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); + curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback')); + curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback')); + + // Request types + switch ($this->verb) { + case 'GET': break; + case 'PUT': + if ($this->fp !== false) { + curl_setopt($curl, CURLOPT_PUT, true); + curl_setopt($curl, CURLOPT_INFILE, $this->fp); + if ($this->size > 0) + curl_setopt($curl, CURLOPT_INFILESIZE, $this->size); + } elseif ($this->data !== false) { + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data); + if ($this->size > 0) + curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size); + } else + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + break; + case 'HEAD': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); + curl_setopt($curl, CURLOPT_NOBODY, true); + break; + case 'DELETE': + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + break; + default: break; + } + + // Execute, grab errors + if (curl_exec($curl)) + $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE); + else + $this->response->error = array( + 'code' => curl_errno($curl), + 'message' => curl_error($curl), + 'resource' => $this->resource + ); + + @curl_close($curl); + + // Parse body into XML + if ($this->response->error === false && isset($this->response->headers['type']) && + $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) { + $this->response->body = simplexml_load_string($this->response->body); + + // Grab S3 errors + if (!in_array($this->response->code, array(200, 204)) && + isset($this->response->body->Code, $this->response->body->Message)) { + $this->response->error = array( + 'code' => (string)$this->response->body->Code, + 'message' => (string)$this->response->body->Message + ); + if (isset($this->response->body->Resource)) + $this->response->error['resource'] = (string)$this->response->body->Resource; + unset($this->response->body); + } + } + + // Clean up file resources + if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp); + + return $this->response; + } + + + /** + * CURL write callback + * + * @param resource &$curl CURL resource + * @param string &$data Data + * @return integer + */ + private function __responseWriteCallback(&$curl, &$data) { + if ($this->response->code == 200 && $this->fp !== false) + return fwrite($this->fp, $data); + else + $this->response->body .= $data; + return strlen($data); + } + + + /** + * CURL header callback + * + * @param resource &$curl CURL resource + * @param string &$data Data + * @return integer + */ + private function __responseHeaderCallback(&$curl, &$data) { + if (($strlen = strlen($data)) <= 2) return $strlen; + if (substr($data, 0, 4) == 'HTTP') + $this->response->code = (int)substr($data, 9, 3); + else { + list($header, $value) = explode(': ', trim($data)); + if ($header == 'Last-Modified') + $this->response->headers['time'] = strtotime($value); + elseif ($header == 'Content-Length') + $this->response->headers['size'] = (int)$value; + elseif ($header == 'Content-Type') + $this->response->headers['type'] = $value; + elseif ($header == 'ETag') + $this->response->headers['hash'] = substr($value, 1, -1); + elseif (preg_match('/^x-amz-meta-.*$/', $header)) + $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value; + } + return $strlen; + } + +} +?> \ No newline at end of file diff --git a/ieducar/intranet/atendidos_cad.php b/ieducar/intranet/atendidos_cad.php index 7052dd0..0394da2 100755 --- a/ieducar/intranet/atendidos_cad.php +++ b/ieducar/intranet/atendidos_cad.php @@ -37,6 +37,7 @@ require_once 'include/clsCadastro.inc.php'; require_once 'include/pessoa/clsCadastroRaca.inc.php'; require_once 'include/pessoa/clsCadastroFisicaRaca.inc.php'; require_once 'include/pmieducar/clsPmieducarAluno.inc.php'; +require_once 'include/pessoa/clsCadastroFisicaFoto.inc.php'; require_once 'App/Model/ZonaLocalizacao.php'; @@ -44,6 +45,7 @@ require_once 'Portabilis/String/Utils.php'; require_once 'Portabilis/View/Helper/Application.php'; require_once 'Portabilis/Utils/Validation.php'; require_once 'Portabilis/Date/Utils.php'; +require_once 'image_check.php'; /** * clsIndex class. @@ -109,6 +111,10 @@ class indice extends clsCadastro var $caminho_det; var $caminho_lst; + // Variáveis para controle da foto + var $objPhoto; + var $arquivoFoto; + function Inicializar() { $this->cod_pessoa_fj = @$_GET['cod_pessoa_fj']; @@ -167,6 +173,21 @@ class indice extends clsCadastro $this->campoOculto('cod_pessoa_fj', $this->cod_pessoa_fj); $this->campoTexto('nm_pessoa', 'Nome', $this->nm_pessoa, '50', '255', TRUE); + $foto = false; + if (is_numeric($this->cod_pessoa_fj)){ + $objFoto = new ClsCadastroFisicaFoto($this->cod_pessoa_fj); + $detalheFoto = $objFoto->detalhe(); + if(count($detalheFoto)) + $foto = $detalheFoto['caminho']; + } else + $foto=false; + + if ($foto!=false){ + $this->campoRotulo('fotoAtual_','Foto atual',''); + $this->campoArquivo('file','Trocar foto',$this->arquivoFoto,40,'
* Recomenda-se imagens nos formatos jpeg, jpg, png e gif. Tamanho máximo: 150KB'); + }else + $this->campoArquivo('file','Foto',$this->arquivoFoto,40,'
* Recomenda-se imagens nos formatos jpeg, jpg, png e gif. Tamanho máximo: 150KB'); + // ao cadastrar pessoa do pai ou mãe apartir do cadastro de outra pessoa, // é enviado o tipo de cadastro (pai ou mae). @@ -925,8 +946,12 @@ class indice extends clsCadastro if (! $this->validatesCpf($this->id_federal)) return false; + if (!$this->validatePhoto()) + return false; + $pessoaId = $this->createOrUpdatePessoa($pessoaIdOrNull); + $this->savePhoto($pessoaId); $this->createOrUpdatePessoaFisica($pessoaId); $this->createOrUpdateDocumentos($pessoaId); $this->createOrUpdateTelefones($pessoaId); @@ -936,6 +961,52 @@ class indice extends clsCadastro return true; } + + //envia foto e salva caminha no banco + protected function savePhoto($id){ + + if ($this->objPhoto!=null){ + + $caminhoFoto = $this->objPhoto->sendPicture($id); + if ($caminhoFoto!=''){ + //new clsCadastroFisicaFoto($id)->exclui(); + $obj = new clsCadastroFisicaFoto($id,$caminhoFoto); + $detalheFoto = $obj->detalhe(); + if (is_array($detalheFoto) && count($detalheFoto)>0) + $obj->edita(); + else + $obj->cadastra(); + + return true; + } else{ + echo ''; + return false; + } + } + } + + // Retorna true caso a foto seja válida + protected function validatePhoto(){ + + $this->arquivoFoto = $_FILES["file"]; + if (!empty($this->arquivoFoto["name"])){ + $this->objPhoto = new PictureController($this->arquivoFoto); + if ($this->objPhoto->validatePicture()){ + return TRUE; + } else { + $this->mensagem = $this->objPhoto->getErrorMessage(); + return false; + } + return false; + }else{ + $this->objPhoto = null; + return true; + } + + } + + + protected function createOrUpdatePessoa($pessoaId = null) { $pessoa = new clsPessoa_(); $pessoa->idpes = $pessoaId; diff --git a/ieducar/intranet/atendidos_det.php b/ieducar/intranet/atendidos_det.php index 59f178f..497d98f 100755 --- a/ieducar/intranet/atendidos_det.php +++ b/ieducar/intranet/atendidos_det.php @@ -32,6 +32,7 @@ require_once 'include/clsBase.inc.php'; require_once 'include/clsDetalhe.inc.php'; require_once 'include/clsBanco.inc.php'; require_once 'include/pessoa/clsCadastroRaca.inc.php'; +require_once 'include/pessoa/clsCadastroFisicaFoto.inc.php'; require_once 'include/pessoa/clsCadastroFisicaRaca.inc.php'; require_once 'App/Model/ZonaLocalizacao.php'; @@ -86,7 +87,15 @@ class indice extends clsDetalhe 'ddd_fax', 'fone_fax', 'email', 'url', 'tipo', 'sexo', 'zona_localizacao' ); - $this->addDetalhe(array('Nome', $detalhe['nome'])); + + $objFoto = new clsCadastroFisicaFoto($cod_pessoa); + $caminhoFoto = $objFoto->detalhe(); + if ($caminhoFoto!=false) + $this->addDetalhe(array('Nome', $detalhe['nome'].' +

')); + else + $this->addDetalhe(array('Nome', $detalhe['nome'])); + $this->addDetalhe(array('CPF', int2cpf($detalhe['cpf']))); if ($detalhe['data_nasc']) { diff --git a/ieducar/intranet/educar_aluno_det.php b/ieducar/intranet/educar_aluno_det.php index a86a1e6..e4cad0f 100644 --- a/ieducar/intranet/educar_aluno_det.php +++ b/ieducar/intranet/educar_aluno_det.php @@ -37,6 +37,8 @@ require_once 'App/Model/ZonaLocalizacao.php'; require_once 'Educacenso/Model/AlunoDataMapper.php'; require_once 'Transporte/Model/AlunoDataMapper.php'; +require_once 'include/pessoa/clsCadastroFisicaFoto.inc.php'; + require_once 'Portabilis/View/Helper/Application.php'; /** @@ -135,6 +137,11 @@ class indice extends clsDetalhe $det_raca = $obj_raca->detalhe(); } + $objFoto = new clsCadastroFisicaFoto($this->ref_idpes); + $detalheFoto = $objFoto->detalhe(); + if ($detalheFoto) + $caminhoFoto = $detalheFoto['caminho']; + $registro['nome_aluno'] = strtoupper($det_pessoa_fj['nome']); $registro['cpf'] = int2IdFederal($det_fisica['cpf']); $registro['data_nasc'] = dataToBrasil($det_fisica['data_nasc']); @@ -376,7 +383,10 @@ class indice extends clsDetalhe } if ($registro['nome_aluno']) { - $this->addDetalhe(array('Nome Aluno', $registro['nome_aluno'])); + if ($caminhoFoto!=null and $caminhoFoto!='') + $this->addDetalhe(array('Nome Aluno', $registro['nome_aluno'].'

')); + else + $this->addDetalhe(array('Nome Aluno', $registro['nome_aluno'])); } if (idFederal2int($registro['cpf'])) { diff --git a/ieducar/intranet/image_check.php b/ieducar/intranet/image_check.php new file mode 100644 index 0000000..3983b84 --- /dev/null +++ b/ieducar/intranet/image_check.php @@ -0,0 +1,162 @@ + + * + * Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo + * sob os termos da Licença Pública Geral GNU conforme publicada pela Free + * Software Foundation; tanto a versão 2 da Licença, como (a seu critério) + * qualquer versão posterior. + * + * Este programa é distribuí­do na expectativa de que seja útil, porém, SEM + * NENHUMA GARANTIA; nem mesmo a garantia implí­cita de COMERCIABILIDADE OU + * ADEQUAÇÃO A UMA FINALIDADE ESPECÃFICA. Consulte a Licença Pública Geral + * do GNU para mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral do GNU junto + * com este programa; se não, escreva para a Free Software Foundation, Inc., no + * endereço 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA. + * + * @author Lucas Schmoeller da Silva + * @category i-Educar + * @license @@license@@ + * @package Api + * @subpackage Modules + * @since Arquivo disponível desde a versão ? + * @version $Id$ + */ + +class PictureController { + + var $imageFile; + var $errorMessage; + var $maxWidth; + var $maxHeight; + var $maxSize; + var $suportedExtensions; + var $imageName; + + function PictureController($imageFile, $maxWidth = NULL, $maxHeight = NULL, $maxSize = NULL, + $suportedExtensions = NULL){ + + + $this->imageFile = $imageFile; + + + if ($maxWidth!=null) + $this->maxWidth = $maxWidth; + else + $this->maxWidth = 500; + + if ($maxHeight!=null) + $this->maxHeight = $maxHeight; + else + $this->maxHeight = 500; + + if ($maxSize!=null) + $this->maxSize = $maxSize; + else + $this->maxSize = 150*1024; + + if ($suportedExtensions != null) + $this->suportedExtensions = $suportedExtensions; + else + $this->suportedExtensions = array('jpeg','jpg','gif','png'); + } + + /** + * Envia imagem caso seja válida e retorna caminho + * + * @author Lucas Schmoeller da Silva - lucas@portabilis.com + * @return String + */ + function sendPicture($imageName){ + + $this->imageName = $imageName; + $tmp = $this->imageFile["tmp_name"]; + include('s3_config.php'); + //Rename image name. + + $actual_image_name = $directory.$this->imageName; + if($s3->putObjectFile($tmp, $bucket , $actual_image_name, S3::ACL_PUBLIC_READ) ) + { + + $s3file='http://'.$bucket.'.s3.amazonaws.com/'.$actual_image_name; + return $s3file; + } + else{ + $this->errorMessage = "Ocorreu um erro no servidor ao enviar foto. Tente novamente."; + return ''; + } + } + + /** + * Verifica se a imagem é válida + * + * @author Lucas Schmoeller da Silva - lucas@portabilis.com + * @return boolean + */ + function validatePicture(){ + + $msg=''; + + $name = $this->imageFile["name"]; + $size = $this->imageFile["size"]; + $ext = $this->getExtension($name); + + + if(strlen($name) > 0) + { + // Verifica formato do arquivo + if(in_array($ext,$this->suportedExtensions)) + { + // Verifica tamanho do arquivo + // @TODO Validar largura e altura da imagem + if($size < $this->maxSize){ + return true; + } + else{ + $this->errorMessage = "Não é permitido fotos com mais de 150KB."; + return false; + } + } + else{ + $this->errorMessage = "Deve ser enviado uma imagem do tipo jpeg, jpg, png ou gif."; + return false; + } + } + else{ + $this->errorMessage = "Selecione uma imagem."; + return false; + } + $this->errorMessage = "Imagem inválida."; + return false; + } + + /** + * Retorna a mensagem de erro + * + * @author Lucas Schmoeller da Silva - lucas@portabilis.com + * @return String + */ + function getErrorMessage(){ + return $this->errorMessage; + } + + + function getExtension($name) + { + $i = strrpos($name,"."); + if (!$i) + return ""; + $l = strlen($name) - $i; + $ext = substr($name,$i+1,$l); + + return $ext; + } +} + +?> \ No newline at end of file diff --git a/ieducar/intranet/s3_config.php b/ieducar/intranet/s3_config.php new file mode 100644 index 0000000..2853143 --- /dev/null +++ b/ieducar/intranet/s3_config.php @@ -0,0 +1,17 @@ +app->aws->bucketname; +$directory=$GLOBALS['coreExt']['Config']->app->database->dbname.'/'; +$key = $GLOBALS['coreExt']['Config']->app->aws->awsacesskey; +$secretKey = $GLOBALS['coreExt']['Config']->app->aws->awssecretkey; + +if (!class_exists('S3')) + require_once 'S3.php'; + +//instantiate the class +$s3 = new S3($key, $secretKey); + +$s3->putBucket($bucket, S3::ACL_PUBLIC_READ); +?> \ No newline at end of file -- libgit2 0.21.2