コード例 #1
0
ファイル: File.php プロジェクト: AndreyTepaykin/Platform
 /**
  * Saves a file, usually sent by the client
  * @method save
  * @static
  * @param {array} $params 
  * @param {string} [$params.data] the file data
  * @param {string} [$params.path="uploads"] parent path under web dir (see subpath)
  * @param {string} [$params.subpath=""] subpath that should follow the path, to save the image under
  * @param {string} [$params.name] override the name of the file, after the subpath
  * @param {string} [$params.skipAccess=false] if true, skips the check for authorization to write files there
  * @param {boolean} [$params.audio] set this to true if the file is an audio file
  * @return {array} Returns array containing ($name => $tailUrl) pair
  */
 static function save($params)
 {
     if (empty($params['data'])) {
         throw new Q_Exception(array('field' => 'file'), 'data');
     }
     // check whether we can write to this path, and create dirs if needed
     $data = $params['data'];
     $audio = $params['audio'];
     $path = isset($params['path']) ? $params['path'] : 'uploads';
     $subpath = isset($params['subpath']) ? $params['subpath'] : '';
     $realPath = Q::realPath(APP_WEB_DIR . DS . $path);
     if ($realPath === false) {
         throw new Q_Exception_MissingFile(array('filename' => APP_WEB_DIR . DS . $path));
     }
     $name = isset($params['name']) ? $params['name'] : 'file';
     if (!preg_match('/^[\\w.-]+$/', $name)) {
         $info = pathinfo($name);
         $name = Q_Utils::normalize($info['filename']) . '.' . $info['extension'];
     }
     // TODO: recognize some extensions maybe
     $writePath = $realPath . ($subpath ? DS . $subpath : '');
     $lastChar = substr($writePath, -1);
     if ($lastChar !== DS and $lastChar !== '/') {
         $writePath .= DS;
     }
     $skipAccess = !empty($params['skipAccess']);
     Q_Utils::canWriteToPath($writePath, $skipAccess ? null : true, true);
     file_put_contents($writePath . $name, $data);
     $size = filesize($writePath . $name);
     $tailUrl = $subpath ? "{$path}/{$subpath}/{$name}" : "{$path}/{$name}";
     /**
      * @event Q/file/save {after}
      * @param {string} user the user
      * @param {string} path the path in the url
      * @param {string} subpath the subpath in the url
      * @param {string} name the actual name of the file
      * @param {string} writePath the actual folder where the path is written
      * @param {string} data the data written to the file
      * @param {string} tailUrl consists of $path/[$subpath/]$name
      * @param {integer} size the size of the file that was written
      * @param {boolean} skipAccess whether we are skipping access checks
      * @param {boolean} audio whether the file is audio
      */
     Q::event('Q/file/save', compact('path', 'subpath', 'name', 'writePath', 'data', 'tailUrl', 'size', 'skipAccess', 'audio'), 'after');
     return array($name => $tailUrl);
 }
コード例 #2
0
ファイル: File.php プロジェクト: dmitriz/Platform
 /**
  * Saves a file, usually sent by the client
  * @method save
  * @static
  * @param {array} $params 
  * @param {string} [$params.data] the file data
  * @param {string} [$params.path="uploads"] parent path under web dir (see subpath)
  * @param {string} [$params.subpath=""] subpath that should follow the path, to save the image under
  * @param {string} [$params.name] override the name of the file, after the subpath
  * @param {string} [$params.skipAccess=false] if true, skips the check for authorization to write files there
  * @return {array} Returns array containing ($name => $tailUrl) pair
  */
 static function save($params)
 {
     if (empty($params['data'])) {
         throw new Q_Exception(array('field' => 'file'), 'data');
     }
     // check whether we can write to this path, and create dirs if needed
     $data = $params['data'];
     $path = isset($params['path']) ? $params['path'] : 'uploads';
     $subpath = isset($params['subpath']) ? $params['subpath'] : '';
     $realPath = Q::realPath(APP_WEB_DIR . DS . $path);
     if ($realPath === false) {
         throw new Q_Exception_MissingFile(array('filename' => APP_WEB_DIR . DS . $path));
     }
     $name = isset($params['name']) ? $params['name'] : 'file';
     if (!preg_match('/^[\\w.-]+$/', $name)) {
         $info = pathinfo($name);
         $name = Q_Utils::normalize($info['filename']) . '.' . $info['extension'];
     }
     // TODO: recognize some extensions maybe
     $writePath = $realPath . ($subpath ? DS . $subpath : '');
     $lastChar = substr($writePath, -1);
     if ($lastChar !== DS and $lastChar !== '/') {
         $writePath .= DS;
     }
     $throwIfNotWritable = empty($params['skipAccess']) ? true : null;
     Q_Utils::canWriteToPath($writePath, $throwIfNotWritable, true);
     file_put_contents($writePath . DS . $name, $data);
     $tailUrl = $subpath ? "{$path}/{$subpath}/{$name}" : "{$path}/{$name}";
     /**
      * @event Q/file/save {after}
      * @param {string} user
      * @param {string} path
      * @param {string} subpath
      * @param {string} name
      * @param {string} writePath
      * @param {string} data
      */
     Q::event('Q/file/save', compact('path', 'subpath', 'name', 'writePath', 'data', 'tailUrl'), 'after');
     return array($name => $tailUrl);
 }
コード例 #3
0
ファイル: Users.php プロジェクト: AndreyTepaykin/Platform
 /**
  * Imports an icon and sets $user->icon to the url.
  * @method importIcon
  * @static
  * @param {array} $user The user for whom the icon should be downloaded
  * @param {array} [$urls=array()] Array of urls
  * @param {string} [$directory=null] Defaults to APP/files/APP/uploads/Users/USERID/icon/imported
  * @return {string} the path to the icon directory
  */
 static function importIcon($user, $urls = array(), $directory = null)
 {
     if (empty($directory)) {
         $app = Q_Config::expect('Q', 'app');
         $directory = APP_FILES_DIR . DS . $app . DS . 'uploads' . DS . 'Users' . DS . Q_Utils::splitId($user->id) . DS . 'icon' . DS . 'imported';
     }
     if (empty($urls)) {
         return $directory;
     }
     Q_Utils::canWriteToPath($directory, false, true);
     $type = Q_Config::get('Users', 'login', 'iconType', 'wavatar');
     $largestSize = 0;
     $largestUrl = null;
     $largestImage = null;
     foreach ($urls as $basename => $url) {
         if (!is_string($url)) {
             continue;
         }
         $filename = $directory . DS . $basename;
         $info = pathinfo($filename);
         $size = $info['filename'];
         if ((string) (int) $size !== $size) {
             continue;
         }
         if ($largestSize < (int) $size) {
             $largestSize = (int) $size;
             $largestUrl = $url;
         }
     }
     if ($largestSize) {
         $largestImage = imagecreatefromstring(file_get_contents($largestUrl));
     }
     foreach ($urls as $basename => $url) {
         if (is_string($url)) {
             $filename = $directory . DS . $basename;
             $info = pathinfo($filename);
             $size = $info['filename'];
             $success = false;
             if ($largestImage and (string) (int) $size === $size) {
                 if ($size == $largestSize) {
                     $image = $largestImage;
                     $success = true;
                 } else {
                     $image = imagecreatetruecolor($size, $size);
                     imagealphablending($image, false);
                     $success = imagecopyresampled($image, $largestImage, 0, 0, 0, 0, $size, $size, $largestSize, $largestSize);
                 }
             }
             if (!$success) {
                 $ch = curl_init();
                 curl_setopt($ch, CURLOPT_URL, $url);
                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                 $data = curl_exec($ch);
                 curl_close($ch);
                 $image = imagecreatefromstring($data);
             }
             $info = pathinfo($filename);
             switch ($info['extension']) {
                 case 'png':
                     $func = 'imagepng';
                     imagesavealpha($image, true);
                     imagealphablending($image, true);
                     break;
                 case 'jpeg':
                 case 'jpeg':
                     $func = 'imagejpeg';
                     break;
                 case 'gif':
                     $func = 'imagegif';
                     break;
             }
             call_user_func($func, $image, $directory . DS . $info['filename'] . '.png');
         } else {
             Q_Image::put($directory . DS . $basename, $url['hash'], $url['size'], $type, Q_Config::get('Users', 'login', 'gravatar', false));
         }
     }
     $head = APP_FILES_DIR . DS . $app . DS . 'uploads';
     $tail = str_replace(DS, '/', substr($directory, strlen($head)));
     $user->icon = '{{baseUrl}}/uploads' . $tail;
     return $directory;
 }
コード例 #4
0
ファイル: Streams.php プロジェクト: atirjavid/Platform
 /**
  * Invites a user (or a future user) to a stream .
  * @method invite
  * @static
  * @param {string} $publisherId The id of the stream publisher
  * @param {string} $streamName The name of the stream the user will be invited to
  * @param {array} $who Array that can contain the following keys:
  * @param {string|array} [$who.userId] user id or an array of user ids
  * @param {string|array} [$who.fb_uid]  fb user id or array of fb user ids
  * @param {string|array} [$who.label]  label or an array of labels, or tab-delimited string
  * @param {string|array} [$who.identifier]  identifier or an array of identifiers, or tab-delimited string
  * @param {integer} [$who.newFutureUsers] the number of new Users_User objects to create via Users::futureUser in order to invite them to this stream. This typically is used in conjunction with passing the "html" option to this function.
  * @param {array} [$options=array()]
  *  @param {string|array} [$options.label] label or an array of labels for adding publisher's contacts
  *  @param {string|array} [$options.myLabel] label or an array of labels for adding logged-in user's contacts
  *  @param {integer} [$options.readLevel] => the read level to grant those who are invited
  *  @param {integer} [$options.writeLevel] => the write level to grant those who are invited
  *  @param {integer} [$options.adminLevel] => the admin level to grant those who are invited
  *	@param {string} [$options.displayName] => the display name to use to represent the inviting user
  *  @param {string} [$options.appUrl] => Can be used to override the URL to which the invited user will be redirected and receive "Q.Streams.token" in the querystring.
  *	@param {array} [$options.html] => an array of ($template, $batchName) such as ("MyApp/foo.handlebars", "foo") for generating html snippets which can then be viewed from and printed via the action Streams/invitations?batchName=$batchName
  * @param {array} [$options.asUserId=null] Invite as this user id
  * @see Users::addLink()
  * @return {array} returns array with keys "success", "invited", "statuses", "identifierTypes", "alreadyParticipating"
  */
 static function invite($publisherId, $streamName, $who, $options = array())
 {
     if (isset($options['asUserId'])) {
         $asUserId = $options['asUserId'];
         $asUser = Users_User::fetch($asUserId);
     } else {
         $asUser = Users::loggedInUser(true);
         $asUserId = $asUser->id;
     }
     // Fetch the stream as the logged-in user
     $stream = Streams::fetch($asUserId, $publisherId, $streamName);
     if (!$stream) {
         throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName');
     }
     $stream = reset($stream);
     // Do we have enough admin rights to invite others to this stream?
     if (!$stream->testAdminLevel('invite') || !$stream->testWriteLevel('join')) {
         throw new Users_Exception_NotAuthorized();
     }
     if (isset($options['html'])) {
         $html = $options['html'];
         if (!is_array($html) or count($html) < 2) {
             throw new Q_Exception_WrongType(array('field' => "options.html", 'type' => 'array of 2 strings'));
         }
         list($template, $batchName) = $html;
         // validate these paths
         $filename = APP_VIEWS_DIR . DS . $template;
         if (!Q::realPath($filename)) {
             throw new Q_Exception_MissingFile(compact('filename'));
         }
         $ext = $pathinfo = pathinfo($template, PATHINFO_EXTENSION);
         if ($ext !== 'handlebars') {
             throw new Q_Exception_WrongValue(array('field' => 'options.html[0]', 'range' => 'a filename with extension .handlebars'));
         }
         $path = Streams::invitationsPath($asUserId) . DS . $batchName;
         Q_Utils::canWriteToPath($path, true, true);
     }
     // get user ids if any to array, throw if user not found
     $raw_userIds = isset($who['userId']) ? Users_User::verifyUserIds($who['userId'], true) : array();
     // merge labels if any
     if (isset($who['label'])) {
         $label = $who['label'];
         if (is_string($label)) {
             $label = array_map('trim', explode("\t", $labels));
         }
         $raw_userIds = array_merge($raw_userIds, Users_User::labelsToIds($asUserId, $label));
     }
     // merge identifiers if any
     $identifierType = null;
     $statuses = null;
     if (isset($who['identifier'])) {
         $identifier = $who['identifier'];
         if (is_string($identifier)) {
             if (Q_Valid::email($who['identifier'])) {
                 $identifierType = 'email';
             } else {
                 if (Q_Valid::phone($who['identifier'])) {
                     $identifierType = 'mobile';
                 }
             }
             $identifier = array_map('trim', explode("\t", $identifier));
         }
         $statuses = array();
         $identifier_ids = Users_User::idsFromIdentifiers($identifier, $statuses);
         $raw_userIds = array_merge($raw_userIds, $identifier_ids);
     }
     // merge fb uids if any
     if (isset($who['fb_uid'])) {
         $fb_uids = $who['fb_uid'];
         if (is_string($fb_uids)) {
             $fb_uids = array_map('trim', explode("\t", $fb_uids));
         }
         $raw_userIds = array_merge($raw_userIds, Users_User::idsFromFacebook($fb_uids));
     }
     if (!empty($who['newFutureUsers'])) {
         $nfu = $who['newFutureUsers'];
         for ($i = 0; $i < $nfu; ++$i) {
             $raw_userIds[] = Users::futureUser('none', null)->id;
         }
     }
     // ensure that each userId is included only once
     // and remove already participating users
     $raw_userIds = array_unique($raw_userIds);
     $total = count($raw_userIds);
     $userIds = Streams_Participant::filter($raw_userIds, $stream);
     $to_invite = count($userIds);
     $appUrl = !empty($options['appUrl']) ? $options['appUrl'] : Q_Request::baseUrl() . '/' . Q_Config::get("Streams", "types", $stream->type, "invite", "url", "plugins/Streams/stream");
     // now check and define levels for invited user
     $readLevel = isset($options['readLevel']) ? $options['readLevel'] : null;
     if (isset($readLevel)) {
         if (!$stream->testReadLevel($readLevel)) {
             // We can't assign greater read level to other people than we have ourselves!
             throw new Users_Exception_NotAuthorized();
         }
     }
     $writeLevel = isset($options['writeLevel']) ? $options['writeLevel'] : null;
     if (isset($writeLevel)) {
         if (!$stream->testWriteLevel($writeLevel)) {
             // We can't assign greater write level to other people than we have ourselves!
             throw new Users_Exception_NotAuthorized();
         }
     }
     $adminLevel = isset($options['adminLevel']) ? $options['adminLevel'] : null;
     if (isset($adminLevel)) {
         if (!$stream->testAdminLevel($adminLevel + 1)) {
             // We can't assign an admin level greater, or equal, to our own!
             // A stream's publisher can assign owners. Owners can assign admins.
             // Admins can confer powers to invite others, to some people.
             // Those people can confer the privilege to publish a message re this stream.
             // But admins can't assign other admins, and even stream owners
             // can't assign other owners.
             throw new Users_Exception_NotAuthorized();
         }
     }
     // calculate expiry time
     $duration = Q_Config::get("Streams", "types", $stream->type, "invite", "duration", false);
     $expiry = $duration ? strtotime($duration) : null;
     // let node handle the rest, and get the result
     $params = array("Q/method" => "Streams/Stream/invite", "invitingUserId" => $asUserId, "username" => $asUser->username, "userIds" => Q::json_encode($userIds), "stream" => Q::json_encode($stream->toArray()), "appUrl" => $appUrl, "label" => Q::ifset($options, 'label', null), "myLabel" => Q::ifset($options, 'myLabel', null), "readLevel" => $readLevel, "writeLevel" => $writeLevel, "adminLevel" => $adminLevel, "displayName" => isset($options['displayName']) ? $options['displayName'] : Streams::displayName($asUser), "expiry" => $expiry);
     if ($template) {
         $params['template'] = $template;
         $params['batchName'] = $batchName;
     }
     $result = Q_Utils::queryInternal('Q/node', $params);
     return array('success' => $result, 'invited' => $userIds, 'statuses' => $statuses, 'identifierType' => $identifierType, 'alreadyParticipating' => $total - $to_invite);
 }
コード例 #5
0
ファイル: Image.php プロジェクト: atirjavid/Platform
 /**
  * Saves an image, usually sent by the client, in one or more sizes.
  * @method save
  * @static
  * @param {array} $params 
  * @param {string} [$params.data] the image data
  * @param {string} [$params.path="uploads"] parent path under web dir (see subpath)
  * @param {string} [$params.subpath=""] subpath that should follow the path, to save the image under
  * @param {string} [$params.merge=""] path under web dir for an optional image to use as a background
  * @param {string} [$params.crop] array with keys "x", "y", "w", "h" to crop the original image
  * @param {string} [$params.save=array("x" => "")] array of $size => $basename pairs
  *  where the size is of the format "WxH", and either W or H can be empty.
  * @param {string} [$params.skipAccess=false] if true, skips the check for authorization to write files there
  * @return {array} an array of ($size => $fullImagePath) pairs
  */
 static function save($params)
 {
     if (empty($params['data'])) {
         throw new Q_Exception("Image data is missing");
     }
     $imageData = $params['data'];
     $image = imagecreatefromstring($imageData);
     if (!$image) {
         throw new Q_Exception("Image type not supported");
     }
     // image dimensions
     $maxW = Q_Config::get('Q', 'uploads', 'limits', 'image', 'width', 5000);
     $maxH = Q_Config::get('Q', 'uploads', 'limits', 'image', 'height', 5000);
     $iw = imagesx($image);
     $ih = imagesy($image);
     if ($maxW and $iw > $maxW) {
         throw new Q_Exception("Uploaded image width exceeds {$maxW}");
     }
     if ($maxH and $iw > $maxH) {
         throw new Q_Exception("Uploaded image width exceeds {$maxH}");
     }
     // check whether we can write to this path, and create dirs if needed
     $path = isset($params['path']) ? $params['path'] : 'uploads';
     $subpath = isset($params['subpath']) ? $params['subpath'] : '';
     $realPath = Q::realPath(APP_WEB_DIR . DS . $path);
     if ($realPath === false) {
         throw new Q_Exception_MissingFile(array('filename' => APP_WEB_DIR . DS . $path));
     }
     $writePath = $realPath . ($subpath ? DS . $subpath : '');
     $lastChar = substr($writePath, -1);
     if ($lastChar !== DS and $lastChar !== '/') {
         $writePath .= DS;
     }
     $throwIfNotWritable = empty($params['skipAccess']) ? true : null;
     Q_Utils::canWriteToPath($writePath, $throwIfNotWritable, true);
     // check if exif is available
     if (self::isJPEG($imageData)) {
         $exif = exif_read_data("data://image/jpeg;base64," . base64_encode($imageData));
         // rotate original image if necessary (hopefully it's not too large).
         if (!empty($exif['Orientation'])) {
             switch ($exif['Orientation']) {
                 case 3:
                     $image = imagerotate($image, 180, 0);
                     break;
                 case 6:
                     $image = imagerotate($image, -90, 0);
                     break;
                 case 8:
                     $image = imagerotate($image, 90, 0);
                     break;
             }
         }
     }
     $crop = isset($params['crop']) ? $params['crop'] : array();
     $save = !empty($params['save']) ? $params['save'] : array('x' => '');
     // crop parameters - size of source image
     $isw = isset($crop['w']) ? $crop['w'] : $iw;
     $ish = isset($crop['h']) ? $crop['h'] : $ih;
     $isx = isset($crop['x']) ? $crop['x'] : 0;
     $isy = isset($crop['y']) ? $crop['y'] : 0;
     // process requested thumbs
     $data = array();
     $merge = null;
     $m = isset($params['merge']) ? $params['merge'] : null;
     if (isset($m) && strtolower(substr($m, -4)) === '.png') {
         $mergePath = Q::realPath(APP_WEB_DIR . DS . implode(DS, explode('/', $m)));
         if ($mergePath) {
             $merge = imagecreatefrompng($mergePath);
             $mw = imagesx($merge);
             $mh = imagesy($merge);
         }
     }
     foreach ($save as $size => $name) {
         if (empty($name)) {
             // generate a filename
             do {
                 $name = Q_Utils::unique(8) . '.png';
             } while (file_exists($writePath . $name));
         }
         if (strrpos($name, '.') === false) {
             $name .= '.png';
         }
         list($n, $ext) = explode('.', $name);
         $sw = $isw;
         $sh = $ish;
         $sx = $isx;
         $sy = $isy;
         // determine destination image size
         if (!empty($size)) {
             $sa = explode('x', $size);
             if (count($sa) > 1) {
                 if ($sa[0] === '') {
                     if ($sa[1] === '') {
                         $dw = $sw;
                         $dh = $sh;
                     } else {
                         $dh = intval($sa[1]);
                         $dw = $sw * $dh / $sh;
                     }
                 } else {
                     $dw = intval($sa[0]);
                     if ($sa[1] === '') {
                         $dh = $sh * $dw / $sw;
                     } else {
                         $dh = intval($sa[1]);
                     }
                 }
             } else {
                 $dw = $dh = intval($sa[0]);
             }
             // calculate the origin point of source image
             // we have a cropped image of dimension $sw, $sh and need to make new with dimension $dw, $dh
             if ($dw / $sw < $dh / $sh) {
                 // source is wider then destination
                 $new = $dw / $dh * $sh;
                 $sx += round(($sw - $new) / 2);
                 $sw = round($new);
             } else {
                 // source is narrower then destination
                 $new = $dh / $dw * $sw;
                 $sy += round(($sh - $new) / 2);
                 $sh = round($new);
             }
         } else {
             $size = '';
             $dw = $sw;
             $dh = $sh;
         }
         // create destination image
         $maxWidth = Q_Config::get('Q', 'images', 'maxWidth', null);
         $maxHeight = Q_Config::get('Q', 'images', 'maxHeight', null);
         if (isset($maxWidth) and $dw > $maxWidth) {
             throw new Q_Exception("Image width exceeds maximum width of {$dw}");
         }
         if (isset($maxHeight) and $dh > $maxHeight) {
             throw new Q_Exception("Image height exceeds maximum height of {$dh}");
         }
         $thumb = imagecreatetruecolor($dw, $dh);
         $res = $sw === $dw && $sh === $dh ? imagecopy($thumb, $image, 0, 0, $sx, $sy, $sw, $sh) : imagecopyresampled($thumb, $image, 0, 0, $sx, $sy, $dw, $dh, $sw, $sh);
         if (!$res) {
             throw new Q_Exception("Failed to save image file of type '{$ext}'");
         }
         if ($merge) {
             $mergethumb = imagecreatetruecolor($mw, $mh);
             imagesavealpha($mergethumb, false);
             imagealphablending($mergethumb, false);
             if (imagecopyresized($mergethumb, $merge, 0, 0, 0, 0, $dw, $dh, $mw, $mh)) {
                 imagecopy($thumb, $mergethumb, 0, 0, 0, 0, $dw, $dh);
             }
         }
         switch ($ext) {
             case 'jpeg':
             case 'jpeg':
                 $func = 'imagejpeg';
                 break;
             case 'gif':
                 $func = 'imagegif';
                 break;
             case 'png':
             default:
                 $func = 'imagepng';
                 break;
         }
         if ($res = call_user_func($func, $thumb, $writePath . $name)) {
             $data[$size] = $subpath ? "{$path}/{$subpath}/{$name}" : "{$path}/{$name}";
         }
     }
     $data[''] = $subpath ? "{$path}/{$subpath}" : "{$path}";
     /**
      * @event Q/image/save {after}
      * @param {string} user
      * @param {string} path
      * @param {string} subpath
      * @param {string} writePath
      * @param {string} data
      */
     Q::event('Q/image/save', compact('path', 'subpath', 'writePath', 'data', 'save', 'crop'), 'after');
     return $data;
 }