[buddypress-trac] [BuddyPress Trac] #5429: New component to manage BuddyPress "attachments"
buddypress-trac
noreply at wordpress.org
Wed Mar 12 17:02:08 UTC 2014
#5429: New component to manage BuddyPress "attachments"
----------------------------+------------------
Reporter: imath | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: 2.0
Component: All Components | Version:
Severity: normal | Resolution:
Keywords: 2nd-opinion |
----------------------------+------------------
Comment (by imath):
Two weeks have passed since the publication of this ticket. I thought it
was important I make a first "report" of my developments progress for this
component.
We decided in a dev-chat that this component would be developed as a
"feature as a plugin" component. This is, in my opinion, a very good
approach because it will enable us to soon work more collaboratively on
the subject without affecting the BuddyPress core.
Before i publish a first version of the plugin on the BuddyPress github
repository, which I hope will happen in the coming days, I really want it
to be as clean as possible. So I realize it’s taking me more time than I
thought, sorry.
PS: primarly wrote this in french and translated it. If like me you're
more comfortable with this language you can read my first version
[https://docs.google.com/document/d/1tBx3coul707lqQzqFMf4FV0BO_6wqq-
G1M6o9SQW22c/edit?usp=sharing here] ;)
===== New "feature as a plugin" component for BuddyPress =====
Since it is possible that the component integrates BuddyPress core when it
will be mature enough, I think the activation process must be the same
than for the other components : by integrating the components list of the
BuddyPress administration settings page ({{{/ wp-admin/options-
general.php?page=bp-components}}}). I see two interests :
1. only some portions of the code will need to be changed once integrated
in core (such as the path to the include directory of the component files)
2. it allows to apply specific settings in conjunction with the components
from being activated and would be likely to use the "attachments"
component. These settings will directly be handled from this
administration page.
In my local development environment, I created a specific "loader" that
allows me to include it in components list. However, it will be necessary
to make some adjustments to core to make this possible. In Attachments,
you will find a patch (5429.diff) detailing those needs.
=== About the BuddyPress Attachment API ===
The plugin is based on a post_type I named {{{bp_attachment}}}, it draws
heavily on the WordPress post type {{{attachment}}} we could have used to
save time. However, I think there are more advantages to separate things.
1. using the attachment post type would have generated the display of
items in the list of media in the administration and during the use of the
media editor by the administrator. This might lead to confusion and would
need to filter the different queries.
2. Our custom post type can enjoy a custom taxonomy I called
{{{bp_component}}} and allow us to categorize the attachments depending on
the components they’re linked to.
The {{{bp_attachment}}} post type will have a term attribute ( groups ,
messages ... ) and it will be possible to enrich it with metas referencing
the items of the other components it is attached to, eg group_id = 1. The
plugin also provides the ability to attach multiple items to an
attachment. Indeed, it seems important to be able to offer users to link a
file to several groups for example. This is a request that I was often
made to BuddyDrive. So for the BuddyPress attachments component it will
happen :)
Ideally, I think, the other components should indicate they wish to use
the attachments, we will see that later. In the meantime, the plugin is
handling it for a single component : 'groups'.
I preferred to start humbly and see for the other components a bit later.
The 'groups' component is interesting because it acts as a container for
other features and its visibility attributes can be exploited later in
conjonction with the status of the attachment which defaults to 'inherit'.
=== PHP part ===
I preferred to cut different parts of the API in different classes in the
first place. It is always possible to combine them into one at some point
if needed.
1. {{{BP_Attachments_Upload}}} is responsible for managing the uploads. It
includes different filters and actions to enjoy the WordPress Attachments
API to our advantage to create different metas and associations to the
terms of our custom taxonomy .
2. {{{BP_Attachments_Browser}}} sets up and launches the WordPress media
editor to allow its use for our attachments component.
3. {{{BP_Attachments}}} is the main CRUD class for attachments. So far I
have completed the R and D, C is provided by {{{BP_Attachments_Upload}}}
and U is one of the things I still have to work on in the coming days. The
different templates and the WP_List_Table in administration screens will
use it.
4. I still have to create the class {{{BP_Attachments_Groups}}} to manage
the integration of the component within groups.
Each of these classes have "wrapper" functions.
About front end screens: to maximize compatibility with themes, I took the
advantage of using the "plugins" templates provided by BuddyPress:
- {{{'members/single/plugins'}}} for profile pages
- {{{'groups/single/plugins'}}} for groups pages
H3 tag around the hook {{{do_action('bp_template_title')}}} is a bit
annoying , but it's the only drawback I see to this method.
In profile pages, I use $ _GET variables to start. This principle,
however, remains interesting if we opt for the use of Ajax in this section
to provide a fallback mechanism, in case javascript is disabled or broken.
For templates, I use the same markup than other components loops,
replacing the avatar by a thumbnail of the photo or an icon file provided
by WordPress .
Secondary navigation can provide tabs to view all attachments, those he
shared in groups. Eventually we can imagine other tabs for "private"
files, shared with friends, etc. In this part of the plugin, I have to
build templates for groups and those to display the file or edit it. In
the edit template file I plan to list the components linking the file to
allow the user to eventually detach his file from some or attach it to
others. Finally, the use of a custom post type raises two concerns:
1. The post type is only available on the blog ( root_blog ) on which it
is initialized. This means that the use from a child site is not intended
or requires the use of the {{{switch_to_blog()}}} function.
2. This is not necessarily linked, but that's what made me think of it. We
must create a mechanism for users to verify capabilities. Like checking a
user can upload attachments on their profile, to a group, can edit,
delete, etc. I started to build a mapping of capabilities that will be
important to check when the time comes. I think it will be a priority
following the publication of the first version of the plugin.
On this second point, I think we should change the
{{{bp_current_user_can()}}} function to allow it to pass arguments in
order to check a user can create an attachment for a group_id for
instance. I created this adaptation on my local dev. It is integrated in
the patch attached to the ticket (5429.diff).
In the particular case of groups or users avatars, for now I only need a
small change in core. In {{{bp_core_avatar_handle_crop()}}} if
{{{bp_core_delete_existing_avatar()}}} could include the item_id argument,
it would be nice. I’m still wondering about
{{{bp_core_avatar_handle_upload()}}} as the one I use in the plugin is
almost a copy of it. Difference is my use of {{{new WP_Error }}} instead
of {{{bp_core_add_message()}}}.
These attachments will be a little special because they will not create a
{{{ bp_attachment}}} in the posts table or in component upload
directories. They will use the current logic. My choice is guided by a
simplification of the Media Editor for this type of attachment that
incorporates two tabs: Upload and Crop. Which brings me to the most
complex part to me!
=== JavaScript / Ajax / WP Media Editor ===
Since we use a {{{post_type != 'attachment'}}} it forced me to completely
overload the BackBone WordPress model to replace {{{Attachments}}},
{{{Attachment}}} & {{{Query}}} by BuddyPress specific ones eg
{{{bpAttachments}}}....
The main reason is that WordPress is blocking Ajax actions (get/save) by
early bailing after a post_type check :
{{{
if ( 'attachment' != $post['post_type'] )
wp_send_json_error();
}}}
It was also necessary that I "copy and adapt" some functions like the one
that prepares attachments for javascript and the one that builds the url
to the uploaded file, for the same reasons .
About {{{Query}}} I need to integrate arguments to filter attachments by
user, component or item_id.
These changes were quite disturbing for my views "extends". I am just
starting to glimpse the tunnel! (French expression! not sure it’s great in
English: "voir le bout du tunnel")
Another point, version 3.9 of WordPress added, among others, image editing
functions directly inside the Media Editor. For now I am not too focused
on the potential of this new view, but I plan to explore it more deeply
soon especially to avoid using jCrop as
[http://odyniec.net/projects/imgareaselect/ ImgAreaSelect] is included in
the editor.
The introduction of this new feature has temporarily "broken", the
mechanism I had developed and more globally using the "Add Media" button
in the WP_Editor in front end. I proposed a patch on WordPress trac
[https://core.trac.wordpress.org/attachment/ticket/27372/27372.diff
27372.diff]. I am confident about the resolution of the
[https://core.trac.wordpress.org/ticket/21811#comment:66 21811] ticket by
the release of 3.9.
However, this side effect has prompted me to design a fallback mechanism
to keep on being able to create attachments even if Javascript is
unavailable or broken.
=== Privacy ===
"And last but not least!" boonebgorges is right to focus on this point as
we will be expected on the subject, that's for sure. Unfortunately, in
this area, even though WordPress provides a "private" status for its
media, it provides no mechanism to ensure that access to the files is
actually private. We faced this problem for our respective plugins BP Docs
and BuddyDrive. I’ve explored how Easy Digital Downloads or WooCommerce
was dealing with it, it is very similar. It does not cover all situations,
especially when the server software is not Apache.
At the same time, it is likely that the majority of WordPress
configurations use Apache. We can therefore use the .htaccess trick by
default and pair it with a mechanism to check files are not directly
reachable prior to the ability to activate the "private" status of
attachments. I looked at the links you've added to your comment,
boonebgorges, and I think you’re right, our only option is to help
administrators to configure their server so that access to files can be
"private".
For instance we could move an image file in a subdirectory of the main
private directory. Then from the settings of the component, we could
attempt to display the image which if actually loaded would indicate that
the server configuration does not provide ability to share private
attachments. A tutorial could then be published on the codex to list the
available ways to make it happen.
It seems to me that the best practice is to move the main private upload
directory out of the web directory while giving proper permissions to the
www user to write / edit and delete folders and files within that
particular directory.
Then there is the problem of displaying images or other media. Since in
such a case, it is easy to force a download, the display is actually more
problematic especially if we must check each thumbnail upon current logged
in user.
I think the easiest way is to use a general thumbnail to indicate a file
is private. In a similar way WordPress does for files that are not images.
Then we should be able to display the image in its preview or unique view
to limit the impact of having to load WordPress to check file access.
About images, I thought, for a very small time, about using the
post_content field of our {{{bp_attachment}}} post type to fill it with
the base64 encoded version of the image, but I think it may be too heavy
in particular when generating these encoded images.
About the plugin, I’ve included a specific directory for private
attachments. The idea is to use it instead of the public one according to
the status selected of the {{{bp_attachment}}} post_type. In the first
version I will publish on github, I think I will leave this part as a
"todo" to enjoy your inputs on the subject. This is priority number 2
after capabilities management :)
To end this "report": I think I've completed the first version of the
plugin by 60%, and I hope to be able to create the github repository
within the next ten days.
5329.diff contains core adaptations I believe are interesting to be
published into trunk before the 2.0 release. As explained above about
avatars, I will eventually complete it with another patch soon.
--
Ticket URL: <https://buddypress.trac.wordpress.org/ticket/5429#comment:6>
BuddyPress Trac <http://buddypress.org/>
BuddyPress Trac
More information about the buddypress-trac
mailing list