Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ticket/15276] Use storage in avatars #4894

Merged
merged 34 commits into from Sep 8, 2017
Merged

Conversation

rubencm
Copy link
Member

@rubencm rubencm commented Aug 8, 2017

Checklist:

  • Correct branch: master for new features; 3.2.x, 3.1.x for fixes
  • Tests pass
  • Code follows coding guidelines: master / 3.2.x, 3.1.x
  • Commit follows commit message format

This depends on #4893

Tracker ticket (set the ticket ID to your ticket ID):

https://tracker.phpbb.com/browse/PHPBB3-15276


public function file_mimetype($path)
{
return mime_content_type($this->root_path . $path);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am looking that this function is obsolete, but i dont find much information about Fileinfo

$avatar_dir_size = $user->lang['NOT_AVAILABLE'];
}
// Couldn't open Avatar dir.
$avatar_dir_size = $user->lang['NOT_AVAILABLE'];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need here another way to get the avatars total filesize

Copy link
Member

@Nicofuma Nicofuma Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just not possible with most cloud providers. We can check if the local adapter is in use, but otherwise I think you may need to use your cloud provider web interface (and even if it is possible we can't display the avatars usage but only the global one, if you use the same S3 bucket for many things per example).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it may be possible for some providers and I think it can still be useful (even if it displays the global usage).
You could add a get_total_usage or something like that in the provider which will return an array containing the current total usage and the maximum allowed usage (if it exists). If one information is missing its value being replaced by false.

Example: (all numbers are in bytes)
return ['usage' => 9999, 'max' => 10000]
return ['usage' => 9999, 'max' => false]
return ['usage' => false, 'max' => false]

Copy link
Member Author

@rubencm rubencm Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but i cannot get the usage easily.
I think i need to create a provider for the storages, with methods to get the list of files, or the total size.
And in the adapter a method to get the total available space.
Or something like that, i dont know

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, it depends what we want to do.
If we want to track all files then we need a new table yes (we can have a singe table for all storages) but if we just want the current usage of the cloud storage then we can rely on the adapter directly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont know, i still think that is better to do a class for each storage with methods to get the files or somehing like that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry but I don't understand what you have in mind.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, im going to do a concept, but i have to finish other things first

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please create a dedicated ticket for this issue

@rubencm
Copy link
Member Author

rubencm commented Aug 9, 2017

Im pretty sure that i have broken the conversion from phpbb2

echo fread($fp, 8192);
}
fclose($fp);
echo fread($fp, 8192);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe is better to do fwrite('php://output', fread($fp, 8192)); ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually as we have a stream we can use stream_copy_to_stream($fp, 'php://output') http://php.net/manual/fr/function.stream-copy-to-stream.php

@rubencm rubencm force-pushed the ticket/15276 branch 4 times, most recently from 934f8dd to b9b40af Compare August 9, 2017 21:02
{
header("Content-Length: $size");
try {
header('Content-Type: ' . $file_info->size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content-Length

@@ -234,4 +234,19 @@ public function write_stream($path, $resource)
throw new exception('STORAGE_CANNOT_COPY_RESOURCE');
}
}

public function file_properties($path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method should be in the interface

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if from an old commit, i removed this

*/
public function file_image_width($path)
{
return $this->image_dimensions($path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return $this->image_dimensions($path)['image_width'];

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is right, but i think i will remove file_info, i dont like how it works

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But now this won't return the actual width but rather just the output of image_dimensions()?

@Nicofuma
Copy link
Member

better, thanks

@Nicofuma
Copy link
Member

@phpbb/development-team it's ready for review and without commits from another PR now

header('Cache-Control: public');

$image_data = @getimagesize($file_path);
header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Braces on new line please (applies to other parts of the code as well).

protected $path;

/**
* @var array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe an explanation of what properties these are?

*/
protected $properties;

public function __construct($adapter, $path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docblock pls

@@ -30,6 +30,11 @@
die('database not up to date');
}

if (!isset($config['storage\\avatar\\config\\path']) || $config['storage\\avatar\\config\\path'] != 'phpbb\\storage\\provider\\local')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use !== if possible.

@@ -30,6 +30,11 @@
die('database not up to date');
}

if (!isset($config['storage\\avatar\\config\\path']) || $config['storage\\avatar\\config\\path'] != 'phpbb\\storage\\provider\\local')
{
die('use local provider');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should display some translateable error message here i think.

Copy link
Member Author

@rubencm rubencm Aug 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont know what is the purpose of this folder, but none of the strings in this file are translatable


$group_id = (int) $group_id;
$ext = substr(strrchr($old_entry, '.'), 1);
$old_filename = get_avatar_filename($old_entry);
$new_filename = $config['avatar_salt'] . "_g$group_id.$ext";
$new_entry = 'g' . $group_id . '_' . substr(time(), -5) . ".$ext";

$avatar_path = $phpbb_root_path . $config['avatar_path'];
if (@rename($avatar_path . '/'. $old_filename, $avatar_path . '/' . $new_filename))
try
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This modification is not exactly the same as what the code did before which is fine for now, but it may cause problems if this needs to be extended in the future. (meaning error handling could get difficult if there are multiple statements that could throw exceptions).

Copy link
Member Author

@rubencm rubencm Aug 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm, i think it is.
The update query is only executed if rename dont throws an exception

return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']));
}

if ($content_length == 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=== instead of double

@Nicofuma
Copy link
Member

Nicofuma commented Sep 6, 2017

@phpbb/development-team please review it a last time :)

@@ -30,6 +30,11 @@
die('database not up to date');
}

if (!isset($config['storage\\avatar\\config\\path']) || $config['storage\\avatar\\config\\path'] !== 'phpbb\\storage\\provider\\local')
{
die('use local provider');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this message should be improved as for someone not knowing the exact purpose of this might not be able to understand why it's causing a die().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i can rewrite this to use storage, but i dont know under which circunstances this script is used, so i just prevent to use it after changing storage

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think we can leave it like that for now. We should start working on the dev doc soon and include a link here

}
catch (\phpbb\storage\exception\exception $e)
{
// Just dont send this header
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Just don't send this header

{
$fp = @fopen($file_path, 'rb');
// Just dont send this header
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

$sql = 'UPDATE ' . GROUPS_TABLE . '
SET group_avatar = \'' . $db->sql_escape($new_entry) . "'
WHERE group_id = $group_id";
$db->sql_query($sql);
}
catch (\phpbb\storage\exception\exception $e)
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment here

*
* @return bool True if user can upload, false if not
*/
protected function can_upload()
{
return ($this->filesystem->exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on'));
return (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should be using the bantu's ini class? @Nicofuma

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could use it yes

*
* @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif
* @return filespec $file Object "filespec" is returned, all further operations can be done with this object
* @access public
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's both wrong and no longer needed IMHO

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just trash the @access line

$avatar_path = $phpbb_root_path . $config['avatar_path'];

$avatar_path = $phpbb_root_path . $config['storage\\avatar\\config\\path'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, there never was a rule about not having (back-)slashes in config names, but without underscores this somehow looks weird to me and breaking the status quo of having configuration names.

Copy link
Member

@Nicofuma Nicofuma Sep 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I asked him to do that on purpose. For me as there is a status quo of not using \ we can reserved it for internal usage like that and have a guarantee of 0 conflict ever.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal usage means that you're not having any intention to make the path customizable? Then why not mark it as a parameter in a yaml file?

Otherwise I don't understand the term "internal usage" or have a different opinion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the path is customizable from a core page in the acp
but we have a lot of config values related to storage with dynamic names.
Here per example, avatar and path are dynamics the rest is internal. The full name is build internally (including storage, config and )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As personally don't care for this. It's a nice way to prevent conflicts for sure. As long as it doesn't mess up with some dbal

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, okay.. It just looks weird to me but other than that it doesn't do anything harmful, I guess.

*/
protected function get_max_file_size()
{
$max_file_size = $this->upload->max_filesize;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it would have been better to just simply add this as a method to the upload class but oh well

public function upload()
{
$args = func_get_args();
return $this->remote_upload($args[0]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand why this was done this way. What were the original arguments here?

@CHItA
Copy link
Member

CHItA commented Sep 7, 2017

Otherwise it is looking good to me 👍

@Nicofuma Nicofuma merged commit 443c503 into phpbb:master Sep 8, 2017
Nicofuma added a commit that referenced this pull request Sep 8, 2017
[ticket/15276] Use storage in avatars

* github.com:phpbb/phpbb: (34 commits)
  [ticket/15276] Changed annotation
  [ticket/15276] Remove unused code
  [ticket/15276] Revert some changes
  [ticket/15276] Use IniGetWrapper
  [ticket/15276] Add missing dependency
  [ticket/15276] Remove unused dependency
  [ticket/15276] Add missing properties
  [ticket/15276] Use InitGetWrapper
  [ticket/15276] Fix comments
  [ticket/15276] Fix code and add phpdoc
  [ticket/15276] Use stream_copy_to_stream
  [ticket/15276] Fix typo
  [ticket/15276] Use mimetype guesser
  [ticket/15276] Update file_info to get size of images
  [ticket/15276] Update
  [ticket/15276] Remove avatar_path
  [ticket/15276] Remove avatar_path from acp
  [ticket/15276] Use finfo to get mimetype
  [ticket/15276] Update file_info
  [ticket/15276] Fix code style
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants