FINAL suepr merge step : added all modules to this super repos
This commit is contained in:
339
sites/all/modules/contrib/users/profile2/LICENSE.txt
Normal file
339
sites/all/modules/contrib/users/profile2/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
64
sites/all/modules/contrib/users/profile2/README.txt
Normal file
64
sites/all/modules/contrib/users/profile2/README.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Profile2
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Maintainers:
|
||||
* Wolfgang Ziegler (fago), nuppla@zites.net
|
||||
* Joachim Noreiko (joachim), joachim.n+drupal@gmail.com
|
||||
|
||||
|
||||
This modules is designed to be the successor of the core profile module. In
|
||||
contrast to the core module this module provides a new, fieldable 'profile'
|
||||
entity - leverage the power of fields!
|
||||
|
||||
|
||||
Installation
|
||||
-------------
|
||||
|
||||
* Copy the whole profile2 directory to your modules directory and
|
||||
activate the module.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
* Go to /admin/structure/profiles for managing profile types.
|
||||
* By default users may view their profile at /user and edit them at
|
||||
'user/X/edit'.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Profile pages
|
||||
--------------------------------------------------------------------------------
|
||||
Maintainers:
|
||||
* Wolfgang Ziegler (fago), nuppla@zites.net
|
||||
|
||||
This module provides an alternative way for your users to edit their profiles.
|
||||
Instead of integrating with the user account page, it generates a separate page
|
||||
allowing your users to view and edit their profile.
|
||||
|
||||
|
||||
Installation
|
||||
-------------
|
||||
|
||||
* Once profile2 is installed, just active the profile pages module.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
* The module may be enabled per profile-type by checking the checkbox
|
||||
"Provide a separate page for editing profiles." in the profile type's
|
||||
settings.
|
||||
* Users with sufficient permissions (check user permissions) receive a menu
|
||||
item in their user menu, just beside the "My account" menu item.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
General notes
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
* Automatic profile labels can be easily generated based upon a pre-configured
|
||||
pattern using the Rules module. See http://drupal.org/node/1392716 for more
|
||||
details.
|
@@ -0,0 +1,13 @@
|
||||
name = Profile2 translation
|
||||
description = Translate profile2 types.
|
||||
dependencies[] = profile2
|
||||
dependencies[] = i18n_string
|
||||
package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-12-26
|
||||
version = "7.x-1.3"
|
||||
core = "7.x"
|
||||
project = "profile2"
|
||||
datestamp = "1356482021"
|
||||
|
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Profile2 i18n integration module via entity API i18n support.
|
||||
*
|
||||
* @see EntityDefaultI18nController
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info_alter().
|
||||
*/
|
||||
function profile2_i18n_entity_info_alter(&$info) {
|
||||
// Enable i18n support via the entity API.
|
||||
$info['profile2_type']['i18n controller class'] = 'EntityDefaultI18nStringController';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_property_info_alter().
|
||||
*/
|
||||
function profile2_i18n_entity_property_info_alter(&$info) {
|
||||
// Mark some properties as translatable, but also denote that translation
|
||||
// works with i18n_string.
|
||||
foreach (array('label') as $name) {
|
||||
$info['profile2_type']['properties'][$name]['translatable'] = TRUE;
|
||||
$info['profile2_type']['properties'][$name]['i18n string'] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_insert().
|
||||
*/
|
||||
function profile2_i18n_profile2_type_insert($profile_type) {
|
||||
i18n_string_object_update('profile2_type', $profile_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_update().
|
||||
*/
|
||||
function profile2_i18n_profile2_type_update($profile_type) {
|
||||
// Account for name changes.
|
||||
if ($profile_type->original->type != $profile_type->type) {
|
||||
i18n_string_update_context("profile2:profile2_type:{$profile_type->original->type}:*", "profile2:profile2_type:{$profile_type->type}:*");
|
||||
}
|
||||
i18n_string_object_update('profile2_type', $profile_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_delete().
|
||||
*/
|
||||
function profile2_i18n_profile2_type_delete($profile_type) {
|
||||
i18n_string_object_remove('profile2_type', $profile_type);
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
name = Profile2 group access
|
||||
description = Adds Organic groups permissions to control profile access on the group level.
|
||||
core = 7.x
|
||||
dependencies[] = profile2
|
||||
dependencies[] = og
|
||||
package = "Organic groups"
|
||||
; Information added by drupal.org packaging script on 2012-12-26
|
||||
version = "7.x-1.3"
|
||||
core = "7.x"
|
||||
project = "profile2"
|
||||
datestamp = "1356482021"
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Profile2 og access integration module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_og_permission().
|
||||
*/
|
||||
function profile2_og_access_og_permission() {
|
||||
$permissions = array();
|
||||
// Generate per profile type permissions.
|
||||
foreach (profile2_get_types() as $type) {
|
||||
$type_name = check_plain($type->type);
|
||||
$permissions += array(
|
||||
"edit any $type_name profile" => array(
|
||||
'title' => t('%type_name: Edit any profile', array('%type_name' => $type->label)),
|
||||
),
|
||||
"view any $type_name profile" => array(
|
||||
'title' => t('%type_name: View any profile', array('%type_name' => $type->label)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_access().
|
||||
*
|
||||
* @see profile2_profile2_access()
|
||||
*/
|
||||
function profile2_og_access_profile2_access($op, $profile = NULL, $account = NULL) {
|
||||
if (isset($profile) && ($type_name = $profile->type) && $profile->identifier() && $op != 'delete') {
|
||||
// Only return TRUE if og grants access. So other modules may still grant
|
||||
// access in case og does not.
|
||||
if (og_user_access_entity("$op any $type_name profile", 'profile2', $profile, $account)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Adds separate pages for viewing and editing profiles.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Shows the profile page for the current user.
|
||||
*
|
||||
* @see user_page()
|
||||
*/
|
||||
function profile2_page_own($base_path) {
|
||||
global $user;
|
||||
if ($user->uid) {
|
||||
menu_set_active_item($base_path . '/' . $user->uid);
|
||||
return menu_execute_active_handler(NULL, FALSE);
|
||||
}
|
||||
else {
|
||||
return drupal_get_form('user_login');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile view page.
|
||||
*/
|
||||
function profile2_page_view($profile) {
|
||||
return $profile->view('page');
|
||||
}
|
||||
|
||||
/**
|
||||
* The profile edit form.
|
||||
*/
|
||||
function profile2_form($form, &$form_state, $profile) {
|
||||
if (empty($form_state['profiles'])) {
|
||||
$form_state['profiles'][$profile->type] = $profile;
|
||||
}
|
||||
// Prevent invoking the same hooks twice, so tell profile2_attach_form() to
|
||||
// skip invoking the hooks.
|
||||
$form_state['profile2_skip_hook'] = TRUE;
|
||||
profile2_attach_form($form, $form_state);
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
'#weight' => 40,
|
||||
);
|
||||
if (empty($profile->is_new) && user_access('administer profiles')) {
|
||||
$form['actions']['delete'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Delete profile'),
|
||||
'#weight' => 45,
|
||||
'#limit_validation_errors' => array(),
|
||||
'#submit' => array('profile2_form_submit_delete')
|
||||
);
|
||||
}
|
||||
$form['#submit'][] = 'profile2_form_submit';
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile form submit handler.
|
||||
*/
|
||||
function profile2_form_submit($form, &$form_state) {
|
||||
// The profile is being saved by profile2_form_submit_handler().
|
||||
drupal_set_message(t('The changes have been saved.'));
|
||||
$form_state['redirect'] = $form_state['profile2']->path();
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile form submit handler for the delete button.
|
||||
*/
|
||||
function profile2_form_submit_delete($form, &$form_state) {
|
||||
$form_state['redirect'] = $form_state['profile2']->path() . '/delete';
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm form for deleting a profile.
|
||||
*/
|
||||
function profile2_page_delete_confirm_form($form, &$form_state, $profile) {
|
||||
$form_state += array('profile2' => $profile);
|
||||
$confirm_question = t('Are you sure you want to delete profile %label?', array('%label' => $profile->label()));
|
||||
return confirm_form($form, $confirm_question, $profile->path());
|
||||
}
|
||||
|
||||
function profile2_page_delete_confirm_form_submit($form, &$form_state) {
|
||||
$profile = $form_state['profile2'];
|
||||
$profile->delete();
|
||||
drupal_set_message(t('Deleted %label.', array('%label' => $profile->label)));
|
||||
$form_state['redirect'] = 'user/' . $profile->uid;
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
name = Profile2 pages
|
||||
description = Adds separate pages for viewing and editing profiles.
|
||||
core = 7.x
|
||||
dependencies[] = profile2
|
||||
; Information added by drupal.org packaging script on 2012-12-26
|
||||
version = "7.x-1.3"
|
||||
core = "7.x"
|
||||
project = "profile2"
|
||||
datestamp = "1356482021"
|
||||
|
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Adds separate pages for viewing and editing profiles.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function profile2_page_menu() {
|
||||
$items = array();
|
||||
|
||||
// Bugfix for uninstalling the module, see http://drupal.org/node/1008346.
|
||||
if (!module_exists('profile2')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (profile2_get_types() as $type_name => $type) {
|
||||
if (!empty($type->data['use_page'])) {
|
||||
$path = profile2_page_get_base_path($type);
|
||||
$count = count(explode('/', $path));
|
||||
|
||||
$items[$path] = array(
|
||||
'title callback' => 'profile2_page_title',
|
||||
'title arguments' => array($type_name),
|
||||
'page callback' => 'profile2_page_own',
|
||||
'page arguments' => array($path),
|
||||
'access callback' => 'user_access',
|
||||
'access arguments' => array("edit own $type_name profile"),
|
||||
'file' => 'profile2_page.inc',
|
||||
'menu_name' => 'user-menu',
|
||||
);
|
||||
|
||||
$items[$path . '/%profile2_by_uid'] = array(
|
||||
'title callback' => 'profile2_page_title',
|
||||
'title arguments' => array($type_name, $count),
|
||||
'page callback' => 'profile2_page_view',
|
||||
'page arguments' => array($count),
|
||||
'load arguments' => array($type_name),
|
||||
'access callback' => 'profile2_access',
|
||||
'access arguments' => array('view', $count),
|
||||
'file' => 'profile2_page.inc',
|
||||
// Copied over the following hack from user_menu() to avoid $path
|
||||
// appearing in the breadcrumb:
|
||||
//
|
||||
// By assigning a different menu name, this item (and all registered
|
||||
// child paths) are no longer considered as children of 'user'. When
|
||||
// accessing the user account pages, the preferred menu link that is
|
||||
// used to build the active trail (breadcrumb) will be found in this
|
||||
// menu (unless there is more specific link), so the link to 'user' will
|
||||
// not be in the breadcrumb.
|
||||
'menu_name' => 'navigation',
|
||||
);
|
||||
$items[$path . '/%profile2_by_uid/view'] = array(
|
||||
'title' => 'View',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'load arguments' => array($type_name),
|
||||
'weight' => -10,
|
||||
);
|
||||
$items[$path . '/%profile2_by_uid/edit'] = array(
|
||||
'page callback' => 'entity_ui_get_form',
|
||||
'page arguments' => array('profile2', $count),
|
||||
'load arguments' => array($type_name),
|
||||
'access callback' => 'profile2_access',
|
||||
'access arguments' => array('edit', $count),
|
||||
'title' => 'Edit',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
|
||||
'file' => 'profile2_page.inc',
|
||||
);
|
||||
$items[$path . '/%profile2_by_uid/delete'] = array(
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('profile2_page_delete_confirm_form', $count),
|
||||
'load arguments' => array($type_name),
|
||||
'access callback' => 'profile2_access',
|
||||
'access arguments' => array('delete', $count),
|
||||
'title' => 'Delete',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'context' => MENU_CONTEXT_INLINE,
|
||||
'file' => 'profile2_page.inc',
|
||||
);
|
||||
// Devel integration.
|
||||
if (module_exists('devel')) {
|
||||
$devel_path = drupal_get_path('module', 'devel');
|
||||
$items[$path . '/%profile2_by_uid/devel'] = array(
|
||||
'title' => 'Devel',
|
||||
'page callback' => 'devel_load_object',
|
||||
'file' => 'devel.pages.inc',
|
||||
'file path' => $devel_path,
|
||||
'page arguments' => array('profile2', $count),
|
||||
'access arguments' => array('access devel information'),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 100,
|
||||
);
|
||||
$items[$path . '/%profile2_by_uid/devel/load'] = array(
|
||||
'title' => 'Load',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
);
|
||||
$items[$path . '/%profile2_by_uid/devel/render'] = array(
|
||||
'title' => 'Render',
|
||||
'page callback' => 'devel_render_object',
|
||||
'page arguments' => array('profile2', $count),
|
||||
'access arguments' => array('access devel information'),
|
||||
'file' => 'devel.pages.inc',
|
||||
'file path' => $devel_path,
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 100,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu load callback.
|
||||
*
|
||||
* Returns the profile object for the given user. If there is none yet, a new
|
||||
* object is created.
|
||||
*/
|
||||
function profile2_by_uid_load($uid, $type_name) {
|
||||
if ($uid && is_numeric($uid) && ($account = user_load($uid))) {
|
||||
$profile = profile2_load_by_user($account, $type_name);
|
||||
if (!$profile) {
|
||||
$profile = profile2_create(array('type' => $type_name));
|
||||
$profile->setUser($account);
|
||||
$profile->is_new = TRUE;
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base path to use as profile page.
|
||||
*/
|
||||
function profile2_page_get_base_path($profile_type) {
|
||||
// Allow for an easy customization of the page's base path.
|
||||
if (!empty($profile_type->data['page_path'])) {
|
||||
return $profile_type->data['page_path'];
|
||||
}
|
||||
return 'profile-' . $profile_type->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_forms().
|
||||
*/
|
||||
function profile2_page_forms($form_id, $args) {
|
||||
// For efficiency, only act if the third argument is 'profile2'.
|
||||
if (isset($args[2]) && is_string($args[2]) && $args[2] == 'profile2') {
|
||||
$info = entity_get_info('profile2');
|
||||
// Translate bundle form ids to the base form id 'profile2_form'.
|
||||
foreach ($info['bundles'] as $bundle => $bundle_info) {
|
||||
$forms['profile2_edit_' . $bundle . '_form']['callback'] = 'profile2_form';
|
||||
$forms['profile2_edit_' . $bundle . '_form']['wrapper callback'] = 'entity_ui_form_defaults';
|
||||
}
|
||||
return $forms;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_load().
|
||||
*/
|
||||
function profile2_page_profile2_type_load($types) {
|
||||
foreach ($types as $type) {
|
||||
if (!empty($type->data['use_page'])) {
|
||||
// Disable user categories and the user account view.
|
||||
$type->userCategory = FALSE;
|
||||
$type->userView = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info_alter().
|
||||
*/
|
||||
function profile2_page_entity_info_alter(&$entity_info) {
|
||||
// Add new view modes for the page.
|
||||
$entity_info['profile2']['view modes']['page'] = array(
|
||||
'label' => t('Profile page'),
|
||||
'custom settings' => FALSE,
|
||||
);
|
||||
$entity_info['profile2']['view modes']['teaser'] = array(
|
||||
'label' => t('Teaser'),
|
||||
'custom settings' => FALSE,
|
||||
);
|
||||
$entity_info['profile2']['uri callback'] = 'profile2_page_uri_callback';
|
||||
$entity_info['profile2']['form callback'] = 'profile2_page_form_callback';
|
||||
}
|
||||
|
||||
/**
|
||||
* URI callback pointing to the profile page.
|
||||
*
|
||||
* @see profile2_pages_entity_info_alter()
|
||||
*/
|
||||
function profile2_page_uri_callback($profile) {
|
||||
$type = $profile->type();
|
||||
if (!empty($type->data['use_page'])) {
|
||||
return array('path' => profile2_page_get_base_path($type) . '/' . $profile->uid);
|
||||
}
|
||||
// Fall back to the default callback.
|
||||
return $profile->defaultUri();
|
||||
}
|
||||
|
||||
/**
|
||||
* Form callback for entity_form().
|
||||
*/
|
||||
function profile2_page_form_callback($profile) {
|
||||
// Pre-populate the form-state with the right form include.
|
||||
$form_state = form_state_defaults();
|
||||
form_load_include($form_state, 'inc', 'profile2_page');
|
||||
return entity_ui_get_form('profile2', $profile, 'edit', $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu title callback.
|
||||
*/
|
||||
function profile2_page_title($type_name, $profile2 = NULL) {
|
||||
$type = profile2_get_types($type_name);
|
||||
// If no profile is given, we are at the general path pointing to the own
|
||||
// profile.
|
||||
if (!isset($profile2)) {
|
||||
return t('My @profile-label', array('@profile-label' => drupal_strtolower($type->getTranslation('label'))));
|
||||
}
|
||||
return drupal_ucfirst($profile2->label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for the profile2 type form..
|
||||
*/
|
||||
function profile2_page_form_profile2_type_form_alter(&$form, &$form_state) {
|
||||
$type = $form_state['profile2_type'];
|
||||
$form['data']['use_page'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Provide a separate page for editing profiles.'),
|
||||
'#description' => t('If enabled, a separate menu item for editing the profile is generated and the profile is hidden from the user account page.'),
|
||||
'#default_value' => !empty($type->is_new) || !empty($type->data['use_page']),
|
||||
);
|
||||
$form['data']['#tree'] = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_insert().
|
||||
*/
|
||||
function profile2_page_profile2_type_insert(ProfileType $type) {
|
||||
// Do not directly issue menu rebuilds here to avoid potentially multiple
|
||||
// rebuilds. Instead, let menu_get_item() issue the rebuild on the next page.
|
||||
if (!empty($type->data['use_page'])) {
|
||||
variable_set('menu_rebuild_needed', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_update().
|
||||
*/
|
||||
function profile2_page_profile2_type_update(ProfileType $type) {
|
||||
// Rebuild the menu if use_page or the type name has been changed.
|
||||
// @see profile2_page_profile2_type_insert()
|
||||
if (empty($type->data['use_page']) != empty($type->original->data['use_page']) || ($type->data['use_page'] && $type->type != $type->original->type)) {
|
||||
variable_set('menu_rebuild_needed', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_delete()
|
||||
*/
|
||||
function profile2_page_profile2_type_delete($type) {
|
||||
// Do not directly issue menu rebuilds here to avoid potentially multiple
|
||||
// rebuilds. Instead, let menu_get_item() issue the rebuild on the next page.
|
||||
if (!empty($type->data['use_page'])) {
|
||||
variable_set('menu_rebuild_needed', TRUE);
|
||||
}
|
||||
}
|
102
sites/all/modules/contrib/users/profile2/profile2.admin.inc
Normal file
102
sites/all/modules/contrib/users/profile2/profile2.admin.inc
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Profile type editing UI.
|
||||
*/
|
||||
|
||||
/**
|
||||
* UI controller.
|
||||
*/
|
||||
class Profile2TypeUIController extends EntityDefaultUIController {
|
||||
|
||||
/**
|
||||
* Overrides hook_menu() defaults.
|
||||
*/
|
||||
public function hook_menu() {
|
||||
$items = parent::hook_menu();
|
||||
$items[$this->path]['description'] = 'Manage profiles, including fields.';
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the profile type editing form.
|
||||
*/
|
||||
function profile2_type_form($form, &$form_state, $profile_type, $op = 'edit') {
|
||||
|
||||
if ($op == 'clone') {
|
||||
$profile_type->label .= ' (cloned)';
|
||||
$profile_type->type = '';
|
||||
}
|
||||
|
||||
$form['label'] = array(
|
||||
'#title' => t('Label'),
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => $profile_type->label,
|
||||
'#description' => t('The human-readable name of this profile type.'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 30,
|
||||
);
|
||||
// Machine-readable type name.
|
||||
$form['type'] = array(
|
||||
'#type' => 'machine_name',
|
||||
'#default_value' => isset($profile_type->type) ? $profile_type->type : '',
|
||||
'#maxlength' => 32,
|
||||
'#disabled' => $profile_type->isLocked() && $op != 'clone',
|
||||
'#machine_name' => array(
|
||||
'exists' => 'profile2_get_types',
|
||||
'source' => array('label'),
|
||||
),
|
||||
'#description' => t('A unique machine-readable name for this profile type. It must only contain lowercase letters, numbers, and underscores.'),
|
||||
);
|
||||
|
||||
$form['data']['#tree'] = TRUE;
|
||||
$form['data']['registration'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show during user account registration.'),
|
||||
'#default_value' => !empty($profile_type->data['registration']),
|
||||
);
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save profile type'),
|
||||
'#weight' => 40,
|
||||
);
|
||||
$form['weight'] = array(
|
||||
'#type' => 'weight',
|
||||
'#title' => t('Weight'),
|
||||
'#default_value' => $profile_type->weight,
|
||||
'#description' => t('When showing profiles, those with lighter (smaller) weights get listed before profiles with heavier (larger) weights.'),
|
||||
'#weight' => 10,
|
||||
);
|
||||
|
||||
if (!$profile_type->isLocked() && $op != 'add' && $op != 'clone') {
|
||||
$form['actions']['delete'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Delete profile type'),
|
||||
'#weight' => 45,
|
||||
'#limit_validation_errors' => array(),
|
||||
'#submit' => array('profile2_type_form_submit_delete')
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form API submit callback for the type form.
|
||||
*/
|
||||
function profile2_type_form_submit(&$form, &$form_state) {
|
||||
$profile_type = entity_ui_form_submit_build_entity($form, $form_state);
|
||||
// Save and go back.
|
||||
$profile_type->save();
|
||||
$form_state['redirect'] = 'admin/structure/profiles';
|
||||
}
|
||||
|
||||
/**
|
||||
* Form API submit callback for the delete button.
|
||||
*/
|
||||
function profile2_type_form_submit_delete(&$form, &$form_state) {
|
||||
$form_state['redirect'] = 'admin/structure/profiles/manage/' . $form_state['profile2_type']->type . '/delete';
|
||||
}
|
313
sites/all/modules/contrib/users/profile2/profile2.api.php
Normal file
313
sites/all/modules/contrib/users/profile2/profile2.api.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains no working PHP code; it exists to provide additional
|
||||
* documentation for doxygen as well as to document hooks in the standard
|
||||
* Drupal manner.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hooks
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Act on profiles being loaded from the database.
|
||||
*
|
||||
* This hook is invoked during profile loading, which is handled by
|
||||
* entity_load(), via the EntityCRUDController.
|
||||
*
|
||||
* @param $entities
|
||||
* An array of profile2 entities being loaded, keyed by id.
|
||||
*
|
||||
* @see hook_entity_load()
|
||||
*/
|
||||
function hook_profile2_load($entities) {
|
||||
$result = db_query('SELECT pid, foo FROM {mytable} WHERE pid IN(:ids)', array(':ids' => array_keys($entities)));
|
||||
foreach ($result as $record) {
|
||||
$entities[$record->pid]->foo = $record->foo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond when a profile is inserted.
|
||||
*
|
||||
* This hook is invoked after the profile is inserted into the database.
|
||||
*
|
||||
* @param profile
|
||||
* The profile that is being inserted.
|
||||
*
|
||||
* @see hook_entity_insert()
|
||||
*/
|
||||
function hook_profile2_insert($profile) {
|
||||
db_insert('mytable')
|
||||
->fields(array(
|
||||
'pid' => $profile->pid,
|
||||
'extra' => $profile->extra,
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on a profile being inserted or updated.
|
||||
*
|
||||
* This hook is invoked before the profile is saved to the database.
|
||||
*
|
||||
* @param $profile
|
||||
* The profile that is being inserted or updated.
|
||||
*
|
||||
* @see hook_entity_presave()
|
||||
*/
|
||||
function hook_profile2_presave($profile) {
|
||||
$profile->extra = 'foo';
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a profile being updated.
|
||||
*
|
||||
* This hook is invoked after the profile has been updated in the database.
|
||||
*
|
||||
* @param $profile
|
||||
* The $profile that is being updated.
|
||||
*
|
||||
* @see hook_entity_update()
|
||||
*/
|
||||
function hook_profile2_update($profile) {
|
||||
db_update('mytable')
|
||||
->fields(array('extra' => $profile->extra))
|
||||
->condition('pid', $profile->pid)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to profile deletion.
|
||||
*
|
||||
* This hook is invoked after the profile has been removed from the database.
|
||||
*
|
||||
* @param $profile
|
||||
* The profile that is being deleted.
|
||||
*
|
||||
* @see hook_entity_delete()
|
||||
*/
|
||||
function hook_profile2_delete($profile) {
|
||||
db_delete('mytable')
|
||||
->condition('pid', $profile->pid)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on a profile that is being assembled before rendering.
|
||||
*
|
||||
* @param $profile
|
||||
* The profile entity.
|
||||
* @param $view_mode
|
||||
* The view mode the profile is rendered in.
|
||||
* @param $langcode
|
||||
* The language code used for rendering.
|
||||
*
|
||||
* The module may add elements to $profile->content prior to rendering. The
|
||||
* structure of $profile->content is a renderable array as expected by
|
||||
* drupal_render().
|
||||
*
|
||||
* @see hook_entity_prepare_view()
|
||||
* @see hook_entity_view()
|
||||
*/
|
||||
function hook_profile2_view($profile, $view_mode, $langcode) {
|
||||
$profile->content['my_additional_field'] = array(
|
||||
'#markup' => $additional_field,
|
||||
'#weight' => 10,
|
||||
'#theme' => 'mymodule_my_additional_field',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the results of entity_view() for profiles.
|
||||
*
|
||||
* @param $build
|
||||
* A renderable array representing the profile content.
|
||||
*
|
||||
* This hook is called after the content has been assembled in a structured
|
||||
* array and may be used for doing processing which requires that the complete
|
||||
* profile content structure has been built.
|
||||
*
|
||||
* If the module wishes to act on the rendered HTML of the profile rather than
|
||||
* the structured content array, it may use this hook to add a #post_render
|
||||
* callback. Alternatively, it could also implement hook_preprocess_profile2().
|
||||
* See drupal_render() and theme() documentation respectively for details.
|
||||
*
|
||||
* @see hook_entity_view_alter()
|
||||
*/
|
||||
function hook_profile2_view_alter($build) {
|
||||
if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
|
||||
// Change its weight.
|
||||
$build['an_additional_field']['#weight'] = -10;
|
||||
|
||||
// Add a #post_render callback to act on the rendered HTML of the entity.
|
||||
$build['#post_render'][] = 'my_module_post_render';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on profile type being loaded from the database.
|
||||
*
|
||||
* This hook is invoked during profile type loading, which is handled by
|
||||
* entity_load(), via the EntityCRUDController.
|
||||
*
|
||||
* @param $types
|
||||
* An array of profiles being loaded, keyed by profile type names.
|
||||
*/
|
||||
function hook_profile2_type_load($types) {
|
||||
if (isset($types['main'])) {
|
||||
$types['main']->userCategory = FALSE;
|
||||
$types['main']->userView = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond when a profile type is inserted.
|
||||
*
|
||||
* This hook is invoked after the profile type is inserted into the database.
|
||||
*
|
||||
* @param $type
|
||||
* The profile type that is being inserted.
|
||||
*/
|
||||
function hook_profile2_type_insert($type) {
|
||||
db_insert('mytable')
|
||||
->fields(array(
|
||||
'id' => $type->id,
|
||||
'extra' => $type->extra,
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on a profile type being inserted or updated.
|
||||
*
|
||||
* This hook is invoked before the profile type is saved to the database.
|
||||
*
|
||||
* @param $type
|
||||
* The profile type that is being inserted or updated.
|
||||
*/
|
||||
function hook_profile2_type_presave($type) {
|
||||
$type->extra = 'foo';
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to updates to a profile.
|
||||
*
|
||||
* This hook is invoked after the profile type has been updated in the database.
|
||||
*
|
||||
* @param $type
|
||||
* The profile type that is being updated.
|
||||
*/
|
||||
function hook_profile2_type_update($type) {
|
||||
db_update('mytable')
|
||||
->fields(array('extra' => $type->extra))
|
||||
->condition('id', $type->id)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to profile type deletion.
|
||||
*
|
||||
* This hook is invoked after the profile type has been removed from the
|
||||
* database.
|
||||
*
|
||||
* @param $type
|
||||
* The profile type that is being deleted.
|
||||
*/
|
||||
function hook_profile2_type_delete($type) {
|
||||
db_delete('mytable')
|
||||
->condition('id', $type->id)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define default profile type configurations.
|
||||
*
|
||||
* @return
|
||||
* An array of default profile types, keyed by profile type names.
|
||||
*/
|
||||
function hook_default_profile2_type() {
|
||||
$types['main'] = new ProfileType(array(
|
||||
'type' => 'main',
|
||||
'label' => t('Profile'),
|
||||
'weight' => 0,
|
||||
'locked' => TRUE,
|
||||
));
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter default profile type configurations.
|
||||
*
|
||||
* @param $defaults
|
||||
* An array of default profile types, keyed by type names.
|
||||
*
|
||||
* @see hook_default_profile2_type()
|
||||
*/
|
||||
function hook_default_profile2_type_alter(&$defaults) {
|
||||
$defaults['main']->label = 'custom label';
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter profile2 forms.
|
||||
*
|
||||
* Modules may alter the profile2 entity form regardless to which form it is
|
||||
* attached by making use of this hook or the profile type specifiy
|
||||
* hook_form_profile2_edit_PROFILE_TYPE_form_alter(). #entity_builders may be
|
||||
* used in order to copy the values of added form elements to the entity, just
|
||||
* as described by entity_form_submit_build_entity().
|
||||
*
|
||||
* @param $form
|
||||
* Nested array of form elements that comprise the form.
|
||||
* @param $form_state
|
||||
* A keyed array containing the current state of the form.
|
||||
*
|
||||
* @see profile2_attach_form()
|
||||
*/
|
||||
function hook_form_profile2_form_alter(&$form, &$form_state) {
|
||||
// Your alterations.
|
||||
}
|
||||
|
||||
/**
|
||||
* Control access to profiles.
|
||||
*
|
||||
* Modules may implement this hook if they want to have a say in whether or not
|
||||
* a given user has access to perform a given operation on a profile.
|
||||
*
|
||||
* @param $op
|
||||
* The operation being performed. One of 'view', 'edit' (being the same as
|
||||
* 'create' or 'update') and 'delete'.
|
||||
* @param $profile
|
||||
* (optional) A profile to check access for. If nothing is given, access for
|
||||
* all profiles is determined.
|
||||
* @param $account
|
||||
* (optional) The user to check for. If no account is passed, access is
|
||||
* determined for the global user.
|
||||
* @return boolean
|
||||
* Return TRUE to grant access, FALSE to explicitly deny access. Return NULL
|
||||
* or nothing to not affect the operation.
|
||||
* Access is granted as soon as a module grants access and no one denies
|
||||
* access. Thus if no module explicitly grants access, access will be denied.
|
||||
*
|
||||
* @see profile2_access()
|
||||
*/
|
||||
function hook_profile2_access($op, $profile = NULL, $account = NULL) {
|
||||
if (isset($profile)) {
|
||||
// Explicitly deny access for a 'secret' profile type.
|
||||
if ($profile->type == 'secret' && !user_access('custom permission')) {
|
||||
return FALSE;
|
||||
}
|
||||
// For profiles other than the default profile grant access.
|
||||
if ($profile->type != 'main' && user_access('custom permission')) {
|
||||
return TRUE;
|
||||
}
|
||||
// In other cases do not alter access.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
14
sites/all/modules/contrib/users/profile2/profile2.info
Normal file
14
sites/all/modules/contrib/users/profile2/profile2.info
Normal file
@@ -0,0 +1,14 @@
|
||||
name = Profile2
|
||||
description = Supports configurable user profiles.
|
||||
core = 7.x
|
||||
files[] = profile2.admin.inc
|
||||
files[] = profile2.info.inc
|
||||
files[] = profile2.test
|
||||
dependencies[] = entity
|
||||
configure = admin/structure/profiles
|
||||
; Information added by drupal.org packaging script on 2012-12-26
|
||||
version = "7.x-1.3"
|
||||
core = "7.x"
|
||||
project = "profile2"
|
||||
datestamp = "1356482021"
|
||||
|
81
sites/all/modules/contrib/users/profile2/profile2.info.inc
Normal file
81
sites/all/modules/contrib/users/profile2/profile2.info.inc
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides Entity metadata integration.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extend the defaults.
|
||||
*/
|
||||
class Profile2MetadataController extends EntityDefaultMetadataController {
|
||||
|
||||
public function entityPropertyInfo() {
|
||||
$info = parent::entityPropertyInfo();
|
||||
$properties = &$info[$this->type]['properties'];
|
||||
|
||||
$properties['label'] = array(
|
||||
'label' => t('Label'),
|
||||
'description' => t('The profile label.'),
|
||||
'setter callback' => 'entity_property_verbatim_set',
|
||||
'setter permission' => 'administer profiles',
|
||||
'schema field' => 'label',
|
||||
);
|
||||
|
||||
$properties['type'] = array(
|
||||
'type' => 'profile2_type',
|
||||
'getter callback' => 'entity_property_getter_method',
|
||||
'setter callback' => 'entity_property_verbatim_set',
|
||||
'setter permission' => 'administer profiles',
|
||||
'required' => TRUE,
|
||||
'description' => t('The profile type.'),
|
||||
) + $properties['type'];
|
||||
|
||||
unset($properties['uid']);
|
||||
|
||||
$properties['user'] = array(
|
||||
'label' => t("User"),
|
||||
'type' => 'user',
|
||||
'description' => t("The owner of the profile."),
|
||||
'getter callback' => 'entity_property_getter_method',
|
||||
'setter callback' => 'entity_property_setter_method',
|
||||
'setter permission' => 'administer profiles',
|
||||
'required' => TRUE,
|
||||
'schema field' => 'uid',
|
||||
);
|
||||
|
||||
$properties['created'] = array(
|
||||
'label' => t("Date created"),
|
||||
'type' => 'date',
|
||||
'description' => t("The date the profile was created."),
|
||||
'setter callback' => 'entity_property_verbatim_set',
|
||||
'setter permission' => 'administer profiles',
|
||||
'schema field' => 'created',
|
||||
);
|
||||
$properties['changed'] = array(
|
||||
'label' => t("Date changed"),
|
||||
'type' => 'date',
|
||||
'schema field' => 'changed',
|
||||
'description' => t("The date the profile was most recently updated."),
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_property_info_alter().
|
||||
*/
|
||||
function profile2_entity_property_info_alter(&$info) {
|
||||
// Add related profiles to the user object.
|
||||
$properties = &$info['user']['properties'];
|
||||
foreach (profile2_get_types() as $type_name => $type) {
|
||||
$properties['profile_' . $type_name] = array(
|
||||
'type' => 'profile2',
|
||||
'label' => t('@type_name profile', array('@type_name' => drupal_ucfirst($type->label))),
|
||||
'description' => t("The users's @type_name profile.", array('@type_name' => $type->label)),
|
||||
'getter callback' => 'profile2_user_get_properties',
|
||||
'bundle' => $type_name,
|
||||
);
|
||||
}
|
||||
}
|
206
sites/all/modules/contrib/users/profile2/profile2.install
Normal file
206
sites/all/modules/contrib/users/profile2/profile2.install
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the profile module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function profile2_install() {
|
||||
// Add an initial profile type, but only if installed manually. In case the
|
||||
// module is installed via an installation profile, skip that.
|
||||
if (!drupal_installation_attempted()) {
|
||||
$type = entity_create('profile2_type', array(
|
||||
'type' => 'main',
|
||||
'label' => t('Main profile'),
|
||||
'weight' => 0,
|
||||
'data' => array('registration' => TRUE, 'use_page' => TRUE),
|
||||
));
|
||||
$type->save();
|
||||
user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('edit own main profile', 'view own main profile'));
|
||||
drupal_set_message(t('A main profile type has been created and assigned to all users. Go to the <a href="!url">Profile types</a> page to add some fields or to configure further profile types.', array('!url' => url('admin/structure/profiles'))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function profile2_schema() {
|
||||
$schema['profile'] = array(
|
||||
'description' => 'Stores profile items.',
|
||||
'fields' => array(
|
||||
'pid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary Key: Unique profile item ID.',
|
||||
),
|
||||
'type' => array(
|
||||
'description' => 'The {profile_type}.type of this profile.',
|
||||
'type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'uid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'default' => NULL,
|
||||
'description' => "The {users}.uid of the associated user.",
|
||||
),
|
||||
'label' => array(
|
||||
'description' => 'A human-readable label for this profile.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'created' => array(
|
||||
'description' => 'The Unix timestamp when the profile was created.',
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'changed' => array(
|
||||
'description' => 'The Unix timestamp when the profile was most recently saved.',
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'uid' => array('uid'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'uid' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
'type' => array(
|
||||
'table' => 'profile_type',
|
||||
'columns' => array('type' => 'type'),
|
||||
),
|
||||
),
|
||||
'primary key' => array('pid'),
|
||||
);
|
||||
|
||||
$schema['profile_type'] = array(
|
||||
'description' => 'Stores information about all defined profile types.',
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary Key: Unique profile type ID.',
|
||||
),
|
||||
'type' => array(
|
||||
'description' => 'The machine-readable name of this profile type.',
|
||||
'type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'label' => array(
|
||||
'description' => 'The human-readable name of this profile type.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'weight' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The weight of this profile type in relation to others.',
|
||||
),
|
||||
'data' => array(
|
||||
'type' => 'text',
|
||||
'not null' => FALSE,
|
||||
'size' => 'big',
|
||||
'serialize' => TRUE,
|
||||
'description' => 'A serialized array of additional data related to this profile type.',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
// Set the default to ENTITY_CUSTOM without using the constant as it is
|
||||
// not safe to use it at this point.
|
||||
'default' => 0x01,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The exportable status of the entity.',
|
||||
),
|
||||
'module' => array(
|
||||
'description' => 'The name of the providing module if the entity has been defined in code.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'type' => array('type'),
|
||||
),
|
||||
);
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add in the exportable entity db columns as required by the entity API.
|
||||
*/
|
||||
function profile2_update_7100() {
|
||||
db_add_field('profile_type', 'status', array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => ENTITY_CUSTOM,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The exportable status of the entity.',
|
||||
));
|
||||
db_add_field('profile_type', 'module', array(
|
||||
'description' => 'The name of the providing module if the entity has been defined in code.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a label column to profiles.
|
||||
*/
|
||||
function profile2_update_7101() {
|
||||
db_add_field('profile', 'label', array(
|
||||
'description' => 'A human-readable label for this profile.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
));
|
||||
$types = db_select('profile_type', 'p')
|
||||
->fields('p')
|
||||
->execute()
|
||||
->fetchAllAssoc('type');
|
||||
|
||||
// Initialize with the type label.
|
||||
foreach ($types as $type_name => $type) {
|
||||
db_update('profile')
|
||||
->fields(array(
|
||||
'label' => $type->label,
|
||||
))
|
||||
->condition('type', $type_name)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a created and a changed column to profiles.
|
||||
*/
|
||||
function profile2_update_7102() {
|
||||
db_add_field('profile', 'created', array(
|
||||
'description' => 'The Unix timestamp when the profile was created.',
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
));
|
||||
db_add_field('profile', 'changed', array(
|
||||
'description' => 'The Unix timestamp when the profile was most recently saved.',
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
));
|
||||
}
|
881
sites/all/modules/contrib/users/profile2/profile2.module
Normal file
881
sites/all/modules/contrib/users/profile2/profile2.module
Normal file
@@ -0,0 +1,881 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Support for configurable user profiles.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info().
|
||||
*/
|
||||
function profile2_entity_info() {
|
||||
$return = array(
|
||||
'profile2' => array(
|
||||
'label' => t('Profile'),
|
||||
'plural label' => t('Profiles'),
|
||||
'description' => t('Profile2 user profiles.'),
|
||||
'entity class' => 'Profile',
|
||||
'controller class' => 'EntityAPIController',
|
||||
'base table' => 'profile',
|
||||
'fieldable' => TRUE,
|
||||
'view modes' => array(
|
||||
'account' => array(
|
||||
'label' => t('User account'),
|
||||
'custom settings' => FALSE,
|
||||
),
|
||||
),
|
||||
'entity keys' => array(
|
||||
'id' => 'pid',
|
||||
'bundle' => 'type',
|
||||
'label' => 'label',
|
||||
),
|
||||
'bundles' => array(),
|
||||
'bundle keys' => array(
|
||||
'bundle' => 'type',
|
||||
),
|
||||
'label callback' => 'entity_class_label',
|
||||
'uri callback' => 'entity_class_uri',
|
||||
'access callback' => 'profile2_access',
|
||||
'module' => 'profile2',
|
||||
'metadata controller class' => 'Profile2MetadataController'
|
||||
),
|
||||
);
|
||||
|
||||
// Add bundle info but bypass entity_load() as we cannot use it here.
|
||||
$types = db_select('profile_type', 'p')
|
||||
->fields('p')
|
||||
->execute()
|
||||
->fetchAllAssoc('type');
|
||||
|
||||
foreach ($types as $type => $info) {
|
||||
$return['profile2']['bundles'][$type] = array(
|
||||
'label' => $info->label,
|
||||
'admin' => array(
|
||||
'path' => 'admin/structure/profiles/manage/%profile2_type',
|
||||
'real path' => 'admin/structure/profiles/manage/' . $type,
|
||||
'bundle argument' => 4,
|
||||
'access arguments' => array('administer profiles'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Support entity cache module.
|
||||
if (module_exists('entitycache')) {
|
||||
$return['profile2']['field cache'] = FALSE;
|
||||
$return['profile2']['entity cache'] = TRUE;
|
||||
}
|
||||
|
||||
$return['profile2_type'] = array(
|
||||
'label' => t('Profile type'),
|
||||
'plural label' => t('Profile types'),
|
||||
'description' => t('Profiles types of Profile2 user profiles.'),
|
||||
'entity class' => 'ProfileType',
|
||||
'controller class' => 'EntityAPIControllerExportable',
|
||||
'base table' => 'profile_type',
|
||||
'fieldable' => FALSE,
|
||||
'bundle of' => 'profile2',
|
||||
'exportable' => TRUE,
|
||||
'entity keys' => array(
|
||||
'id' => 'id',
|
||||
'name' => 'type',
|
||||
'label' => 'label',
|
||||
),
|
||||
'access callback' => 'profile2_type_access',
|
||||
'module' => 'profile2',
|
||||
// Enable the entity API's admin UI.
|
||||
'admin ui' => array(
|
||||
'path' => 'admin/structure/profiles',
|
||||
'file' => 'profile2.admin.inc',
|
||||
'controller class' => 'Profile2TypeUIController',
|
||||
),
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu argument loader; Load a profile type by string.
|
||||
*
|
||||
* @param $type
|
||||
* The machine-readable name of a profile type to load.
|
||||
* @return
|
||||
* A profile type array or FALSE if $type does not exist.
|
||||
*/
|
||||
function profile2_type_load($type) {
|
||||
return profile2_get_types($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function profile2_permission() {
|
||||
$permissions = array(
|
||||
'administer profile types' => array(
|
||||
'title' => t('Administer profile types'),
|
||||
'description' => t('Create and delete fields on user profiles, and set their permissions.'),
|
||||
),
|
||||
'administer profiles' => array(
|
||||
'title' => t('Administer profiles'),
|
||||
'description' => t('Edit and view all user profiles.'),
|
||||
),
|
||||
);
|
||||
// Generate per profile type permissions.
|
||||
foreach (profile2_get_types() as $type) {
|
||||
$type_name = check_plain($type->type);
|
||||
$permissions += array(
|
||||
"edit own $type_name profile" => array(
|
||||
'title' => t('%type_name: Edit own profile', array('%type_name' => $type->getTranslation('label'))),
|
||||
),
|
||||
"edit any $type_name profile" => array(
|
||||
'title' => t('%type_name: Edit any profile', array('%type_name' => $type->getTranslation('label'))),
|
||||
),
|
||||
"view own $type_name profile" => array(
|
||||
'title' => t('%type_name: View own profile', array('%type_name' => $type->getTranslation('label'))),
|
||||
),
|
||||
"view any $type_name profile" => array(
|
||||
'title' => t('%type_name: View any profile', array('%type_name' => $type->getTranslation('label'))),
|
||||
),
|
||||
);
|
||||
}
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of all profile types, keyed by the type name.
|
||||
*
|
||||
* @param $type_name
|
||||
* If set, the type with the given name is returned.
|
||||
* @return ProfileType[]
|
||||
* Depending whether $type isset, an array of profile types or a single one.
|
||||
*/
|
||||
function profile2_get_types($type_name = NULL) {
|
||||
$types = entity_load_multiple_by_name('profile2_type', isset($type_name) ? array($type_name) : FALSE);
|
||||
return isset($type_name) ? reset($types) : $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a profile object.
|
||||
*
|
||||
* @param $pid
|
||||
* Integer specifying the profile id.
|
||||
* @param $reset
|
||||
* A boolean indicating that the internal cache should be reset.
|
||||
* @return
|
||||
* A fully-loaded $profile object or FALSE if it cannot be loaded.
|
||||
*
|
||||
* @see profile2_load_multiple()
|
||||
*/
|
||||
function profile2_load($pid, $reset = FALSE) {
|
||||
$profiles = profile2_load_multiple(array($pid), array(), $reset);
|
||||
return reset($profiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load multiple profiles based on certain conditions.
|
||||
*
|
||||
* @param $pids
|
||||
* An array of profile IDs.
|
||||
* @param $conditions
|
||||
* An array of conditions to match against the {profile} table.
|
||||
* @param $reset
|
||||
* A boolean indicating that the internal cache should be reset.
|
||||
* @return
|
||||
* An array of profile objects, indexed by pid.
|
||||
*
|
||||
* @see entity_load()
|
||||
* @see profile2_load()
|
||||
* @see profile2_load_by_user()
|
||||
*/
|
||||
function profile2_load_multiple($pids = array(), $conditions = array(), $reset = FALSE) {
|
||||
return entity_load('profile2', $pids, $conditions, $reset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch profiles by account.
|
||||
*
|
||||
* @param $account
|
||||
* The user account to load profiles for, or its uid.
|
||||
* @param $type_name
|
||||
* To load a single profile, pass the type name of the profile to load.
|
||||
* @return
|
||||
* Either a single profile or an array of profiles keyed by profile type.
|
||||
*
|
||||
* @see profile2_load_multiple()
|
||||
* @see profile2_profile2_delete()
|
||||
* @see Profile::save()
|
||||
*/
|
||||
function profile2_load_by_user($account, $type_name = NULL) {
|
||||
// Use a separate query to determine all profile ids per user and cache them.
|
||||
// That way we can look up profiles by id and benefit from the static cache
|
||||
// of the entity loader.
|
||||
$cache = &drupal_static(__FUNCTION__, array());
|
||||
$uid = is_object($account) ? $account->uid : $account;
|
||||
|
||||
if (!isset($cache[$uid])) {
|
||||
if (empty($type_name)) {
|
||||
$profiles = profile2_load_multiple(FALSE, array('uid' => $uid));
|
||||
// Cache ids for further lookups.
|
||||
$cache[$uid] = array();
|
||||
foreach ($profiles as $pid => $profile) {
|
||||
$cache[$uid][$profile->type] = $pid;
|
||||
}
|
||||
return $profiles ? array_combine(array_keys($cache[$uid]), $profiles) : array();
|
||||
}
|
||||
$cache[$uid] = db_select('profile', 'p')
|
||||
->fields('p', array('type', 'pid'))
|
||||
->condition('uid', $uid)
|
||||
->execute()
|
||||
->fetchAllKeyed();
|
||||
}
|
||||
if (isset($type_name)) {
|
||||
return isset($cache[$uid][$type_name]) ? profile2_load($cache[$uid][$type_name]) : FALSE;
|
||||
}
|
||||
// Return an array containing profiles keyed by profile type.
|
||||
return $cache[$uid] ? array_combine(array_keys($cache[$uid]), profile2_load_multiple($cache[$uid])) : $cache[$uid];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_delete().
|
||||
*/
|
||||
function profile2_profile2_delete($profile) {
|
||||
// Clear the static cache from profile2_load_by_user().
|
||||
$cache = &drupal_static('profile2_load_by_user', array());
|
||||
unset($cache[$profile->uid][$profile->type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a profile.
|
||||
*/
|
||||
function profile2_delete(Profile $profile) {
|
||||
$profile->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple profiles.
|
||||
*
|
||||
* @param $pids
|
||||
* An array of profile IDs.
|
||||
*/
|
||||
function profile2_delete_multiple(array $pids) {
|
||||
entity_get_controller('profile2')->delete($pids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_delete().
|
||||
*/
|
||||
function profile2_user_delete($account) {
|
||||
foreach (profile2_load_by_user($account) as $profile) {
|
||||
profile2_delete($profile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new profile object.
|
||||
*/
|
||||
function profile2_create(array $values) {
|
||||
return new Profile($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated. Use profile2_create().
|
||||
*/
|
||||
function profile_create(array $values) {
|
||||
return new Profile($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a profile to the database.
|
||||
*
|
||||
* @param $profile
|
||||
* The profile object.
|
||||
*/
|
||||
function profile2_save(Profile $profile) {
|
||||
return $profile->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a profile type to the db.
|
||||
*/
|
||||
function profile2_type_save(ProfileType $type) {
|
||||
$type->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a profile type from.
|
||||
*/
|
||||
function profile2_type_delete(ProfileType $type) {
|
||||
$type->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_type_delete()
|
||||
*/
|
||||
function profile2_profile2_type_delete(ProfileType $type) {
|
||||
// Delete all profiles of this type but only if this is not a revert.
|
||||
if (!$type->hasStatus(ENTITY_IN_CODE)) {
|
||||
$pids = array_keys(profile2_load_multiple(FALSE, array('type' => $type->type)));
|
||||
if ($pids) {
|
||||
profile2_delete_multiple($pids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_view().
|
||||
*/
|
||||
function profile2_user_view($account, $view_mode, $langcode) {
|
||||
foreach (profile2_get_types() as $type => $profile_type) {
|
||||
if ($profile_type->userView && $profile = profile2_load_by_user($account, $type)) {
|
||||
if (profile2_access('view', $profile)) {
|
||||
$account->content['profile_' . $type] = array(
|
||||
'#type' => 'user_profile_category',
|
||||
'#title' => $profile->label,
|
||||
'#prefix' => '<a id="profile-' . $profile->type . '"></a>',
|
||||
);
|
||||
$account->content['profile_' . $type]['view'] = $profile->view('account');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for the user edit form.
|
||||
*
|
||||
* @see profile2_form_validate_handler
|
||||
* @see profile2_form_submit_handler
|
||||
*/
|
||||
function profile2_form_user_profile_form_alter(&$form, &$form_state) {
|
||||
if (($type = profile2_get_types($form['#user_category'])) && $type->userCategory) {
|
||||
if (empty($form_state['profiles'])) {
|
||||
$profile = profile2_load_by_user($form['#user'], $form['#user_category']);
|
||||
if (empty($profile)) {
|
||||
$profile = profile2_create(array('type' => $form['#user_category'], 'uid' => $form['#user']->uid));
|
||||
}
|
||||
$form_state['profiles'][$profile->type] = $profile;
|
||||
}
|
||||
profile2_attach_form($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for the registration form.
|
||||
*/
|
||||
function profile2_form_user_register_form_alter(&$form, &$form_state) {
|
||||
foreach (profile2_get_types() as $type_name => $profile_type) {
|
||||
if (!empty($profile_type->data['registration'])) {
|
||||
if (empty($form_state['profiles'][$type_name])) {
|
||||
$form_state['profiles'][$type_name] = profile2_create(array('type' => $type_name));
|
||||
}
|
||||
profile2_attach_form($form, $form_state);
|
||||
// Wrap each profile form in a fieldset.
|
||||
$form['profile_' . $type_name] += array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => check_plain($profile_type->getTranslation('label')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the profile forms of the profiles set in
|
||||
* $form_state['profiles'].
|
||||
*
|
||||
* Modules may alter the profile2 entity form regardless to which form it is
|
||||
* attached by making use of hook_form_profile2_form_alter().
|
||||
*
|
||||
* @param $form
|
||||
* The form to which to attach the profile2 form. For each profile the form
|
||||
* is added to @code $form['profile_' . $profile->type] @endcode. This helper
|
||||
* also adds in a validation and a submit handler caring for the attached
|
||||
* profile forms.
|
||||
*
|
||||
* @see hook_form_profile2_form_alter()
|
||||
* @see profile2_form_validate_handler()
|
||||
* @see profile2_form_submit_handler()
|
||||
*/
|
||||
function profile2_attach_form(&$form, &$form_state) {
|
||||
foreach ($form_state['profiles'] as $type => $profile) {
|
||||
$form['profile_' . $profile->type]['#tree'] = TRUE;
|
||||
$form['profile_' . $profile->type]['#parents'] = array('profile_' . $profile->type);
|
||||
field_attach_form('profile2', $profile, $form['profile_' . $profile->type], $form_state);
|
||||
|
||||
if (count(field_info_instances('profile2', $profile->type)) == 0) {
|
||||
$form['profile_' . $profile->type]['message'] = array(
|
||||
'#access' => user_access('administer profile types'),
|
||||
'#markup' => t('No fields have been associated with this profile type. Go to the <a href="!url">Profile types</a> page to add some fields.', array('!url' => url('admin/structure/profiles'))),
|
||||
);
|
||||
}
|
||||
|
||||
// Provide a central place for modules to alter the profile forms, but
|
||||
// skip that in case the caller cares about invoking the hooks.
|
||||
// @see profile2_form().
|
||||
if (!isset($form_state['profile2_skip_hook'])) {
|
||||
$hooks[] = 'form_profile2_edit_' . $type . '_form';
|
||||
$hooks[] = 'form_profile2_form';
|
||||
drupal_alter($hooks, $form, $form_state);
|
||||
}
|
||||
}
|
||||
$form['#validate'][] = 'profile2_form_validate_handler';
|
||||
$form['#submit'][] = 'profile2_form_submit_handler';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation handler for the profile form.
|
||||
*
|
||||
* @see profile2_attach_form()
|
||||
*/
|
||||
function profile2_form_validate_handler(&$form, &$form_state) {
|
||||
foreach ($form_state['profiles'] as $type => $profile) {
|
||||
if (isset($form_state['values']['profile_' . $profile->type])) {
|
||||
// @see entity_form_field_validate()
|
||||
$pseudo_entity = (object) $form_state['values']['profile_' . $profile->type];
|
||||
$pseudo_entity->type = $type;
|
||||
field_attach_form_validate('profile2', $pseudo_entity, $form['profile_' . $profile->type], $form_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler that builds and saves all profiles in the form.
|
||||
*
|
||||
* @see profile2_attach_form()
|
||||
*/
|
||||
function profile2_form_submit_handler(&$form, &$form_state) {
|
||||
profile2_form_submit_build_profile($form, $form_state);
|
||||
// This is needed as some submit callbacks like user_register_submit() rely on
|
||||
// clean form values.
|
||||
profile2_form_submit_cleanup($form, $form_state);
|
||||
|
||||
foreach ($form_state['profiles'] as $type => $profile) {
|
||||
// During registration set the uid field of the newly created user.
|
||||
if (empty($profile->uid) && isset($form_state['user']->uid)) {
|
||||
$profile->uid = $form_state['user']->uid;
|
||||
}
|
||||
profile2_save($profile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit builder. Extracts the form values and updates the profile entities.
|
||||
*
|
||||
* @see profile2_attach_form()
|
||||
*/
|
||||
function profile2_form_submit_build_profile(&$form, &$form_state) {
|
||||
foreach ($form_state['profiles'] as $type => $profile) {
|
||||
// @see entity_form_submit_build_entity()
|
||||
if (isset($form['profile_' . $type]['#entity_builders'])) {
|
||||
foreach ($form['profile_' . $type]['#entity_builders'] as $function) {
|
||||
$function('profile2', $profile, $form['profile_' . $type], $form_state);
|
||||
}
|
||||
}
|
||||
field_attach_submit('profile2', $profile, $form['profile_' . $type], $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the form values as the user modules relies on clean values.
|
||||
*
|
||||
* @see profile2_attach_form()
|
||||
*/
|
||||
function profile2_form_submit_cleanup(&$form, &$form_state) {
|
||||
foreach ($form_state['profiles'] as $type => $profile) {
|
||||
unset($form_state['values']['profile_' . $type]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_categories().
|
||||
*/
|
||||
function profile2_user_categories() {
|
||||
$data = array();
|
||||
foreach (profile2_get_types() as $type => $info) {
|
||||
if ($info->userCategory) {
|
||||
$data[] = array(
|
||||
'name' => $type,
|
||||
'title' => $info->getTranslation('label'),
|
||||
// Add an offset so a weight of 0 appears right of the account category.
|
||||
'weight' => $info->weight + 3,
|
||||
'access callback' => 'profile2_category_access',
|
||||
'access arguments' => array(1, $type)
|
||||
);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu item access callback - check if a user has access to a profile category.
|
||||
*/
|
||||
function profile2_category_access($account, $type_name) {
|
||||
// As there might be no profile yet, create a new object for being able to run
|
||||
// a proper access check.
|
||||
$profile = profile2_create(array('type' => $type_name, 'uid' => $account->uid));
|
||||
return ($account->uid > 0 && $profile->type()->userCategory && profile2_access('edit', $profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given user has access to a profile.
|
||||
*
|
||||
* @param $op
|
||||
* The operation being performed. One of 'view', 'update', 'create', 'delete'
|
||||
* or just 'edit' (being the same as 'create' or 'update').
|
||||
* @param $profile
|
||||
* (optional) A profile to check access for. If nothing is given, access for
|
||||
* all profiles is determined.
|
||||
* @param $account
|
||||
* The user to check for. Leave it to NULL to check for the global user.
|
||||
* @return boolean
|
||||
* Whether access is allowed or not.
|
||||
*
|
||||
* @see hook_profile2_access()
|
||||
* @see profile2_profile2_access()
|
||||
*/
|
||||
function profile2_access($op, $profile = NULL, $account = NULL) {
|
||||
if (user_access('administer profiles', $account)) {
|
||||
return TRUE;
|
||||
}
|
||||
if ($op == 'create' || $op == 'update') {
|
||||
$op = 'edit';
|
||||
}
|
||||
// Allow modules to grant / deny access.
|
||||
$access = module_invoke_all('profile2_access', $op, $profile, $account);
|
||||
|
||||
// Only grant access if at least one module granted access and no one denied
|
||||
// access.
|
||||
if (in_array(FALSE, $access, TRUE)) {
|
||||
return FALSE;
|
||||
}
|
||||
elseif (in_array(TRUE, $access, TRUE)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_profile2_access().
|
||||
*/
|
||||
function profile2_profile2_access($op, $profile = NULL, $account = NULL) {
|
||||
// Don't grant access for users to delete their profile.
|
||||
if (isset($profile) && ($type_name = $profile->type) && $op != 'delete') {
|
||||
if (user_access("$op any $type_name profile", $account)) {
|
||||
return TRUE;
|
||||
}
|
||||
$account = isset($account) ? $account : $GLOBALS['user'];
|
||||
if (isset($profile->uid) && $profile->uid == $account->uid && user_access("$op own $type_name profile", $account)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
// Do not explicitly deny access so others may still grant access.
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback for the entity API.
|
||||
*/
|
||||
function profile2_type_access($op, $type = NULL, $account = NULL) {
|
||||
return user_access('administer profile types', $account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function profile2_theme() {
|
||||
return array(
|
||||
'profile2' => array(
|
||||
'render element' => 'elements',
|
||||
'template' => 'profile2',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The class used for profile entities.
|
||||
*/
|
||||
class Profile extends Entity {
|
||||
|
||||
/**
|
||||
* The profile id.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $pid;
|
||||
|
||||
/**
|
||||
* The name of the profile type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* The profile label.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* The user id of the profile owner.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $uid;
|
||||
|
||||
/**
|
||||
* The Unix timestamp when the profile was created.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $created;
|
||||
|
||||
/**
|
||||
* The Unix timestamp when the profile was most recently saved.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $changed;
|
||||
|
||||
|
||||
public function __construct($values = array()) {
|
||||
if (isset($values['user'])) {
|
||||
$this->setUser($values['user']);
|
||||
unset($values['user']);
|
||||
}
|
||||
if (isset($values['type']) && is_object($values['type'])) {
|
||||
$values['type'] = $values['type']->type;
|
||||
}
|
||||
if (!isset($values['label']) && isset($values['type']) && $type = profile2_get_types($values['type'])) {
|
||||
// Initialize the label with the type label, so newly created profiles
|
||||
// have that as interim label.
|
||||
$values['label'] = $type->label;
|
||||
}
|
||||
parent::__construct($values, 'profile2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user owning this profile.
|
||||
*/
|
||||
public function user() {
|
||||
return user_load($this->uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new user owning this profile.
|
||||
*
|
||||
* @param $account
|
||||
* The user account object or the user account id (uid).
|
||||
*/
|
||||
public function setUser($account) {
|
||||
$this->uid = is_object($account) ? $account->uid : $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated profile type object.
|
||||
*
|
||||
* @return ProfileType
|
||||
*/
|
||||
public function type() {
|
||||
return profile2_get_types($this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full url() for the profile.
|
||||
*/
|
||||
public function url() {
|
||||
$uri = $this->uri();
|
||||
return url($uri['path'], $uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drupal path to this profile.
|
||||
*/
|
||||
public function path() {
|
||||
$uri = $this->uri();
|
||||
return $uri['path'];
|
||||
}
|
||||
|
||||
public function defaultUri() {
|
||||
return array(
|
||||
'path' => 'user/' . $this->uid,
|
||||
'options' => array('fragment' => 'profile-' . $this->type),
|
||||
);
|
||||
}
|
||||
|
||||
public function defaultLabel() {
|
||||
if (module_exists('profile2_i18n')) {
|
||||
// Run the label through i18n_string() using the profile2_type label
|
||||
// context, so the default label (= the type's label) gets translated.
|
||||
return entity_i18n_string('profile2:profile2_type:' . $this->type . ':label', $this->label);
|
||||
}
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function buildContent($view_mode = 'full', $langcode = NULL) {
|
||||
$content = array();
|
||||
// Assume newly create objects are still empty.
|
||||
if (!empty($this->is_new)) {
|
||||
$content['empty']['#markup'] = '<em class="profile2-no-data">' . t('There is no profile data yet.') . '</em>';
|
||||
}
|
||||
return entity_get_controller($this->entityType)->buildContent($this, $view_mode, $langcode, $content);
|
||||
}
|
||||
|
||||
public function save() {
|
||||
// Care about setting created and changed values. But do not automatically
|
||||
// set a created values for already existing profiles.
|
||||
if (empty($this->created) && (!empty($this->is_new) || !$this->pid)) {
|
||||
$this->created = REQUEST_TIME;
|
||||
}
|
||||
$this->changed = REQUEST_TIME;
|
||||
|
||||
parent::save();
|
||||
// Update the static cache from profile2_load_by_user().
|
||||
$cache = &drupal_static('profile2_load_by_user', array());
|
||||
if (isset($cache[$this->uid])) {
|
||||
$cache[$this->uid][$this->type] = $this->pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a separate class for profile types so we can specify some defaults
|
||||
* modules may alter.
|
||||
*/
|
||||
class ProfileType extends Entity {
|
||||
|
||||
/**
|
||||
* Whether the profile type appears in the user categories.
|
||||
*/
|
||||
public $userCategory = TRUE;
|
||||
|
||||
/**
|
||||
* Whether the profile is displayed on the user account page.
|
||||
*/
|
||||
public $userView = TRUE;
|
||||
|
||||
public $type;
|
||||
public $label;
|
||||
public $weight = 0;
|
||||
|
||||
public function __construct($values = array()) {
|
||||
parent::__construct($values, 'profile2_type');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the profile type is locked, thus may not be deleted or renamed.
|
||||
*
|
||||
* Profile types provided in code are automatically treated as locked, as well
|
||||
* as any fixed profile type.
|
||||
*/
|
||||
public function isLocked() {
|
||||
return isset($this->status) && empty($this->is_new) && (($this->status & ENTITY_IN_CODE) || ($this->status & ENTITY_FIXED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden, to introduce the method for old entity API versions (BC).
|
||||
*
|
||||
* @todo Remove once we bump the required entity API version.
|
||||
*/
|
||||
public function getTranslation($property, $langcode = NULL) {
|
||||
if (module_exists('profile2_i18n')) {
|
||||
return parent::getTranslation($property, $langcode);
|
||||
}
|
||||
return $this->$property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Entity::save().
|
||||
*/
|
||||
public function save() {
|
||||
parent::save();
|
||||
// Clear field info caches such that any changes to extra fields get
|
||||
// reflected.
|
||||
field_info_cache_clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View a profile.
|
||||
*
|
||||
* @see Profile::view()
|
||||
*/
|
||||
function profile2_view($profile, $view_mode = 'full', $langcode = NULL, $page = NULL) {
|
||||
return $profile->view($view_mode, $langcode, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORMID_alter().
|
||||
*
|
||||
* Adds a checkbox for controlling field view access to fields added to
|
||||
* profiles.
|
||||
*/
|
||||
function profile2_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
|
||||
if ($form['instance']['entity_type']['#value'] == 'profile2') {
|
||||
$form['field']['settings']['profile2_private'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Make the content of this field private.'),
|
||||
'#default_value' => !empty($form['#field']['settings']['profile2_private']),
|
||||
'#description' => t('If checked, the content of this field is only shown to the profile owner and administrators.'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Add the value to the form so it isn't lost.
|
||||
$form['field']['settings']['profile2_private'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => !empty($form['#field']['settings']['profile2_private']),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_access().
|
||||
*/
|
||||
function profile2_field_access($op, $field, $entity_type, $profile = NULL, $account = NULL) {
|
||||
if ($entity_type == 'profile2' && $op == 'view' && !empty($field['settings']['profile2_private']) && !user_access('administer profiles', $account)) {
|
||||
// For profiles, deny general view access for private fields.
|
||||
if (!isset($profile)) {
|
||||
return FALSE;
|
||||
}
|
||||
// Also deny view access, if someone else views a private field.
|
||||
$account = isset($account) ? $account : $GLOBALS['user'];
|
||||
if ($account->uid != $profile->uid) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_extra_fields().
|
||||
*
|
||||
* We need to add pseudo fields for profile types to allow for weight settings
|
||||
* when viewing a user or filling in the profile types while registrating.
|
||||
*/
|
||||
function profile2_field_extra_fields() {
|
||||
$extra = array();
|
||||
foreach (profile2_get_types() as $type_name => $type) {
|
||||
// Appears on: admin/config/people/accounts/display
|
||||
if (!empty($type->userView)) {
|
||||
$extra['user']['user']['display']['profile_' . $type_name] = array(
|
||||
'label' => t('Profile: @profile', array('@profile' => $type->label)),
|
||||
'weight' => $type->weight,
|
||||
);
|
||||
}
|
||||
// Appears on: admin/config/people/accounts/fields
|
||||
if (!empty($type->data['registration'])) {
|
||||
$extra['user']['user']['form']['profile_' . $type_name] = array(
|
||||
'label' => t('Profile: @profile', array('@profile' => $type->label)),
|
||||
'description' => t('Appears during registration only.'),
|
||||
'weight' => $type->weight,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity metadata callback to load profiles for the given user account.
|
||||
*/
|
||||
function profile2_user_get_properties($account, array $options, $name) {
|
||||
// Remove the leading 'profile_' from the property name to get the type name.
|
||||
$profile = profile2_load_by_user($account, substr($name, 8));
|
||||
return $profile ? $profile : NULL;
|
||||
}
|
||||
|
137
sites/all/modules/contrib/users/profile2/profile2.test
Normal file
137
sites/all/modules/contrib/users/profile2/profile2.test
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Test basic CRUD functionality.
|
||||
*/
|
||||
class Profile2CRUDTestCase extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Editing profiles',
|
||||
'description' => 'Tests basic CRUD and editing of Profile2 profiles.',
|
||||
'group' => 'Profile2',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('profile2', 'locale');
|
||||
|
||||
profile2_type_save(new ProfileType(array(
|
||||
'type' => 'test',
|
||||
'label' => 'label',
|
||||
'weight' => 0
|
||||
)));
|
||||
profile2_type_save(new ProfileType(array(
|
||||
'type' => 'test2',
|
||||
'label' => 'label2',
|
||||
'weight' => 2
|
||||
)));
|
||||
profile2_load_multiple(FALSE, array(), TRUE);
|
||||
|
||||
// Add a field to main type, which is created during module installation.
|
||||
$field = array(
|
||||
'field_name' => 'profile_fullname',
|
||||
'type' => 'text',
|
||||
'cardinality' => 1,
|
||||
'translatable' => FALSE,
|
||||
);
|
||||
field_create_field($field);
|
||||
$instance = array(
|
||||
'entity_type' => 'profile2',
|
||||
'field_name' => 'profile_fullname',
|
||||
'bundle' => 'main',
|
||||
'label' => 'Full name',
|
||||
'description' => 'Specify your first and last name.',
|
||||
'widget' => array(
|
||||
'type' => 'text_textfield',
|
||||
'weight' => 0,
|
||||
),
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests CRUD for a profile related to a user and one unrelated to a user.
|
||||
*/
|
||||
function testCRUD() {
|
||||
$user1 = $this->drupalCreateUser();
|
||||
// Create profiles for the user1 and unrelated to a user.
|
||||
profile2_save(profile2_create(array('type' => 'test', 'uid' => $user1->uid)));
|
||||
profile2_save(profile2_create(array('type' => 'test2', 'uid' => $user1->uid)));
|
||||
$profile = profile2_create(array('type' => 'test', 'uid' => NULL));
|
||||
profile2_save($profile);
|
||||
|
||||
$profiles = profile2_load_by_user($user1);
|
||||
$this->assertEqual($profiles['test']->label(), 'label', 'Created and loaded profile 1.');
|
||||
$this->assertEqual($profiles['test2']->label(), 'label2', 'Created and loaded profile 2.');
|
||||
|
||||
// Test looking up from static cache works also.
|
||||
$profiles = profile2_load_by_user($user1);
|
||||
$this->assertEqual($profiles['test']->label, 'label', 'Looked up profiles again.');
|
||||
|
||||
$loaded = profile2_load($profile->pid);
|
||||
$this->assertEqual($loaded->pid, $profile->pid, 'Loaded profile unrelated to a user.');
|
||||
|
||||
profile2_delete($profiles['test']);
|
||||
$profiles2 = profile2_load_by_user($user1);
|
||||
$this->assertEqual(array_keys($profiles2), array('test2'), 'Profile successfully deleted.');
|
||||
|
||||
profile2_save($profiles2['test2']);
|
||||
$this->assertEqual($profiles['test2']->pid, $profiles2['test2']->pid, 'Profile successfully updated.');
|
||||
|
||||
// Delete a profile type.
|
||||
profile2_type_delete(profile2_get_types('test'));
|
||||
// Try deleting multiple profiles by deleting all existing profiles.
|
||||
$pids = array_keys(profile2_load_multiple(FALSE));
|
||||
profile2_delete_multiple($pids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test registration integration.
|
||||
*/
|
||||
function testRegistrationIntegration() {
|
||||
// Allow registration by site visitors without administrator approval.
|
||||
variable_set('user_register', 1);
|
||||
$edit = array();
|
||||
$edit['name'] = $name = $this->randomName();
|
||||
$edit['mail'] = $mail = $edit['name'] . '@example.com';
|
||||
$edit['profile_main[profile_fullname][und][0][value]'] = $this->randomName();
|
||||
$this->drupalPost('user/register', $edit, t('Create new account'));
|
||||
$this->assertText(t('A welcome message with further instructions has been sent to your e-mail address.'), t('User registered successfully.'));
|
||||
$return = user_load_multiple(array(), array('name' => $name, 'mail' => $mail));
|
||||
$new_user = reset($return);
|
||||
$this->assertTrue($new_user->status, t('New account is active after registration.'));
|
||||
$this->assertEqual(profile2_load_by_user($new_user, 'main')->profile_fullname[LANGUAGE_NONE][0]['value'], $edit['profile_main[profile_fullname][und][0][value]'], 'Profile created.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic edit and display.
|
||||
*/
|
||||
function testEditAndDisplay() {
|
||||
user_role_revoke_permissions(DRUPAL_AUTHENTICATED_RID, array('edit own main profile', 'view own main profile'));
|
||||
$user1 = $this->drupalCreateUser();
|
||||
$this->drupalLogin($user1);
|
||||
// Make sure access is denied to the profile.
|
||||
$this->drupalGet('user/' . $user1->uid . '/edit/main');
|
||||
$this->assertText(t('Access denied'), 'Access has been denied.');
|
||||
|
||||
// Test creating a profile manually (e.g. by an admin) and ensure the user
|
||||
// may not see it.
|
||||
profile2_create(array('type' => 'main', 'uid' => $user1->uid))->save();
|
||||
$this->drupalGet('user/' . $user1->uid);
|
||||
$this->assertNoText(t('Main profile'), 'Profile data is not visible to the owner.');
|
||||
|
||||
$user2 = $this->drupalCreateUser(array('edit own main profile', 'view own main profile'));
|
||||
$this->drupalLogin($user2);
|
||||
|
||||
// Create profiles for the user2.
|
||||
$edit['profile_main[profile_fullname][und][0][value]'] = $this->randomName();
|
||||
$this->drupalPost('user/' . $user2->uid . '/edit/main', $edit, t('Save'));
|
||||
$this->assertText(t('The changes have been saved.'), 'Profile saved.');
|
||||
$this->assertEqual(profile2_load_by_user($user2, 'main')->profile_fullname[LANGUAGE_NONE][0]['value'], $edit['profile_main[profile_fullname][und][0][value]'], 'Profile edited.');
|
||||
|
||||
$this->drupalGet('user/' . $user2->uid);
|
||||
$this->assertText(check_plain($edit['profile_main[profile_fullname][und][0][value]']), 'Profile displayed.');
|
||||
}
|
||||
|
||||
}
|
44
sites/all/modules/contrib/users/profile2/profile2.tpl.php
Normal file
44
sites/all/modules/contrib/users/profile2/profile2.tpl.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Default theme implementation for profiles.
|
||||
*
|
||||
* Available variables:
|
||||
* - $content: An array of comment items. Use render($content) to print them all, or
|
||||
* print a subset such as render($content['field_example']). Use
|
||||
* hide($content['field_example']) to temporarily suppress the printing of a
|
||||
* given element.
|
||||
* - $title: The (sanitized) profile type label.
|
||||
* - $url: The URL to view the current profile.
|
||||
* - $page: TRUE if this is the main view page $url points too.
|
||||
* - $classes: String of classes that can be used to style contextually through
|
||||
* CSS. It can be manipulated through the variable $classes_array from
|
||||
* preprocess functions. By default the following classes are available, where
|
||||
* the parts enclosed by {} are replaced by the appropriate values:
|
||||
* - entity-profile
|
||||
* - profile-{TYPE}
|
||||
*
|
||||
* Other variables:
|
||||
* - $classes_array: Array of html class attribute values. It is flattened
|
||||
* into a string within the variable $classes.
|
||||
*
|
||||
* @see template_preprocess()
|
||||
* @see template_preprocess_entity()
|
||||
* @see template_process()
|
||||
*/
|
||||
?>
|
||||
<div class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
|
||||
|
||||
<?php if (!$page): ?>
|
||||
<h2<?php print $title_attributes; ?>>
|
||||
<a href="<?php print $url; ?>"><?php print $title; ?></a>
|
||||
</h2>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="content"<?php print $content_attributes; ?>>
|
||||
<?php
|
||||
print render($content);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user