first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View File

@@ -0,0 +1,274 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
Cambridge, MA 02139, 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 Library 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

View File

@@ -0,0 +1,23 @@
Styles are containers to group similar field display formatters. For example, a
style on a Filefield may contain several formatters based on the mimetype or
stream, while a style on a node reference might display various formatters
based on the referenced node type.
By itself, this module does nothing. Rather, it provides an API available for
use by other modules. The Media Styles module, bundled with the
<a href="/project/media">Media</a> module, is a fully featured module utilizing
the API.
Hooks provided:
<code>
hook_styles_default_containers()
hook_styles_default_styles()
hook_styles_default_presets()
hook_styles_default_containers_alter(&$style)
hook_styles_default_styles_alter(&$style)
hook_styles_default_presets_alter(&$style)
hook_styles_delete(&$style)
</code>
See http://groups.drupal.org/node/35206 for a quick background.

View File

@@ -0,0 +1,2 @@
Readme for File Styles

View File

@@ -0,0 +1,384 @@
<?php
/**
* @file
* Administrative page callbacks for the File: Styles module.
*/
/**
* Menu callback; Listing of all current File styles.
*/
function file_style_list() {
$page = array();
$styles = file_styles();
$page['file_style_list'] = array(
'#markup' => theme('file_style_list', array('styles' => $styles)),
'#attached' => array(
'css' => array(drupal_get_path('module', 'file_styles') . '/file_styles.admin.css' => array('preprocess' => FALSE)),
),
);
return $page;
}
/**
* Form builder; Form for adding a new file style.
*
* @ingroup forms
* @see file_style_add_form_submit()
* @see file_style_name_validate()
*/
function file_style_add_form($form, &$form_state) {
$form['name'] = array(
'#type' => 'textfield',
'#size' => '64',
'#title' => t('Style name'),
'#default_value' => '',
'#description' => t('The name is used in URLs for generated file. Use only lowercase alphanumeric characters, underscores (_), and hyphens (-).'),
'#element_validate' => array('file_style_name_validate'),
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Create new style'),
);
return $form;
}
/**
* Submit handler for adding a new file style.
*/
function file_style_add_form_submit($form, &$form_state) {
$style = array('name' => $form_state['values']['name']);
$style = file_style_save($style);
drupal_set_message(t('Style %name was created.', array('%name' => $style['name'])));
$form_state['redirect'] = 'admin/config/file/file-styles/edit/' . $style['name'];
}
/**
* Element validate function to ensure unique, URL safe style names.
*/
function file_style_name_validate($element, $form_state) {
// Check for duplicates.
$styles = file_styles();
if (isset($styles[$element['#value']]) && (!isset($form_state['file_style']['msid']) || $styles[$element['#value']]['msid'] != $form_state['file_style']['msid'])) {
form_set_error($element['#name'], t('The file style name %name is already in use.', array('%name' => $element['#value'])));
}
// Check for illegal characters in file style names.
if (preg_match('/[^0-9a-z_\-]/', $element['#value'])) {
form_set_error($element['#name'], t('Please only use lowercase alphanumeric characters, underscores (_), and hyphens (-) for style names.'));
}
}
/**
* Form builder; Edit a file style name and effects order.
*
* @param $form_state
* An associative array containing the current state of the form.
* @param $style
* An file style array.
* @ingroup forms
* @see file_style_form_submit()
* @see file_style_name_validate()
*/
function file_style_form($form, &$form_state, $file_style) {
$title = t('Edit %name style', array('%name' => $file_style['name']));
drupal_set_title($title, PASS_THROUGH);
// Adjust this form for styles that must be overridden to edit.
$editable = (bool) ($file_style['storage'] & IMAGE_STORAGE_EDITABLE);
if (!$editable && empty($form_state['input'])) {
drupal_set_message(t('This file style is currently being provided by a module. Click the "Override defaults" button to change its settings.'), 'warning');
}
$form_state['file_style'] = $file_style;
$form['#tree'] = TRUE;
$form['#attached']['css'][drupal_get_path('module', 'file') . '/file.admin.css'] = array('preprocess' => FALSE);
$form['#attached']['css'][drupal_get_path('module', 'image') . '/image.admin.css'] = array('preprocess' => FALSE);
// // Show the thumbnail preview.
// $form['preview'] = array(
// '#type' => 'item',
// '#title' => t('Preview'),
// '#markup' => theme('file_style_preview', array('style' => $style)),
// );
// Allow the name of the style to be changed, unless this style is
// provided by a module's hook_default_file_styles().
if ($file_style['storage'] & IMAGE_STORAGE_MODULE) {
$form['name'] = array(
'#type' => 'item',
'#title' => t('File style name'),
'#markup' => $file_style['name'],
'#description' => t('This file style is being provided by %module module and may not be renamed.', array('%module' => $style['module'])),
);
}
else {
$form['name'] = array(
'#type' => 'textfield',
'#size' => '64',
'#title' => t('File style name'),
'#default_value' => $file_style['name'],
'#description' => t('The name is used in URLs for generated file. Use only lowercase alphanumeric characters, underscores (_), and hyphens (-).'),
'#element_validate' => array('file_style_name_validate'),
'#required' => TRUE,
);
}
// Build the list of existing file effects for this file style.
$form['effects'] = array(
'#theme' => 'file_style_effects',
);
// foreach ($style['effects'] as $meid => $effect) {
// $form['effects'][$meid]['#weight'] = isset($form_state['input']['effects']) ? $form_state['input']['effects'][$meid]['weight'] : NULL;
// $form['effects'][$meid]['label'] = array(
// '#markup' => $effect['label'],
// );
// $form['effects'][$meid]['summary'] = array(
// '#markup' => isset($effect['summary theme']) ? theme($effect['summary theme'], array('data' => $effect['data'])) : '',
// );
// $form['effects'][$meid]['weight'] = array(
// '#type' => 'weight',
// '#default_value' => $effect['weight'],
// '#access' => $editable,
// );
// $form['effects'][$meid]['configure'] = array(
// '#type' => 'link',
// '#title' => t('edit'),
// '#href' => 'admin/config/file/file-styles/edit/' . $style['name'] . '/effects/' . $effect['meid'],
// '#access' => $editable && isset($effect['form callback']),
// );
// $form['effects'][$meid]['remove'] = array(
// '#type' => 'link',
// '#title' => t('delete'),
// '#href' => 'admin/config/file/file-styles/edit/' . $style['name'] . '/effects/' . $effect['meid'] . '/delete',
// '#access' => $editable,
// );
// }
$form['effects']['tabs'] = array(
'#type' => 'vertical_tabs',
);
// Build the new file effect addition form and add it to the effect list.
foreach (file_effect_definitions() as $definition_name => $definition) {
$form['effects']['tabs'][$definition_name] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#title' => check_plain($definition['label']),
'#description' => t('@label will be applied to the following:<br />Streams: %streams<br />File types: %types', array('@label' => $definition['label'], '%streams' => implode(', ', $definition['streams']), '%types' => implode(', ', $definition['mimetypes']))),
);
$new_effect_options = array(' ' => t('Select a file style to apply'));
foreach ($definition['styles'] as $style_name => $style) {
$effects = array();
foreach ($style['effects'] as $effect) {
$data = array();
foreach ($effect['data'] as $type => $value) {
$data[] = t('@type = @value', array('@type' => $type, '@value' => $value));
}
$effects[] = t('@effect: (@data)', array('@effect' => $effect['label'], '@data' => implode(', ', $data)));
}
$new_effect_options[$style_name] = t('@name - %effects', array('@name' => $style['name'], '%effects' => implode('; ', $effects))); // check_plain($style['name'] . ' ' . implode(', ', $effects));
}
$form['effects']['tabs'][$definition_name]['new'] = array(
'#type' => 'radios',
'#title' => t('Please select a style from the following options:'),
'#options' => $new_effect_options,
'#default_value' => isset($file_style['styles'][$definition_name]) ? $file_style['styles'][$definition_name] : ' ',
);
if (isset($definition['add-new-link'])) {
$form['effects']['tabs'][$definition_name]['new']['#description'] = filter_xss($definition['add-new-link']);
}
if (isset($definition['preview-theme'])) {
// theme_image_style_preview is not properly registered.
module_load_include('inc', 'image', 'image.admin');
// Show the thumbnail preview.
$form['effects']['tabs'][$definition_name]['preview'] = array(
'#type' => 'item',
'#title' => t('Preview'),
'#markup' => theme($definition['preview-theme'], array('style' => $definition['styles']['thumbnail'])),// $file_style['styles'][$definition_name])),
);
}
// $form['effects']['tabs'][$definition_name]['weight'] = array(
// '#type' => 'weight',
// '#default_value' => count($form['effects']['tabs'][$definition_name]) - 1,
// );
}
// $new_effect_options = array('' => t('Select a new effect'));
// foreach (file_effect_definitions() as $effect => $definition) {
// $new_effect_options[$effect] = check_plain($definition['name']);
// }
// $form['effects']['new'] = array(
// '#tree' => FALSE,
// '#weight' => isset($form_state['input']['weight']) ? $form_state['input']['weight'] : NULL,
// '#access' => $editable,
// );
// $form['effects']['new']['new'] = array(
// '#type' => 'radios',
// '#options' => $new_effect_options,
// );
// $form['effects']['new']['add'] = array(
// '#type' => 'submit',
// '#value' => t('Add'),
// '#validate' => array('file_style_form_add_validate'),
// '#submit' => array('file_style_form_submit', 'file_style_form_add_submit'),
// );
// Show the Override or Submit button for this style.
$form['override'] = array(
'#type' => 'submit',
'#value' => t('Override defaults'),
'#validate' => array(),
'#submit' => array('file_style_form_override_submit'),
'#access' => !$editable,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Update style'),
'#access' => $editable,
);
return $form;
}
/**
* Validate handler for adding a new file effect to a file style.
*/
function file_style_form_add_validate($form, &$form_state) {
if (!$form_state['values']['new']) {
form_error($form['effects']['new']['new'], t('Select an effect to add.'));
$form_state['rebuild'] = TRUE;
}
}
/**
* Submit handler for adding a new file effect to a file style.
*/
function file_style_form_add_submit($form, &$form_state) {
$style = $form_state['file_style'];
// Check if this field has any configuration options.
$effect = file_effect_definition_load($form_state['values']['new']);
// Load the configuration form for this option.
if (isset($effect['form callback'])) {
$path = 'admin/config/file/file-styles/edit/' . $form_state['file_style']['name'] . '/add/' . $form_state['values']['new'];
$form_state['redirect'] = array($path, array('query' => array('weight' => $form_state['values']['weight'])));
}
// If there's no form, imfiletely add the file effect.
else {
$effect['isid'] = $style['isid'];
$effect['weight'] = $form_state['values']['weight'];
file_effect_save($effect);
drupal_set_message(t('The file effect was successfully applied.'));
}
}
/**
* Submit handler for overriding a module-defined style.
*/
function file_style_form_override_submit($form, &$form_state) {
drupal_set_message(t('The %style style has been overridden, allowing you to change its settings.', array('%style' => $form_state['file_style']['name'])));
file_default_style_save($form_state['file_style']);
}
/**
* Submit handler for saving a file style.
*/
function file_style_form_submit($form, &$form_state) {
// Update the file style name if it has changed.
$style = $form_state['file_style'];
if (isset($form_state['values']['name']) && $style['name'] != $form_state['values']['name']) {
$style['name'] = $form_state['values']['name'];
}
// Update file effect weights.
if (!empty($form_state['values']['effects'])) {
foreach ($form_state['values']['effects'] as $meid => $effect_data) {
if (isset($style['effects'][$meid])) {
$effect = $style['effects'][$meid];
$effect['weight'] = $effect_data['weight'];
file_effect_save($effect);
}
}
}
file_style_save($style);
if ($form_state['values']['op'] == t('Update style')) {
drupal_set_message('Changes to the style have been saved.');
}
$form_state['redirect'] = 'admin/config/file/file-styles/edit/' . $style['name'];
}
function file_style_delete_form() {
}
function file_style_revert_form() {
}
function file_effect_form() {
}
function file_effect_delete_form() {
}
// function file_effect_form() {
// }
/**
* Display the page containing the list of file styles.
*
* @param $variables
* An associative array containing:
* - styles: An array of all the file styles returned by file_get_styles().
*
* @see file_get_styles()
* @ingroup themeable
*/
function theme_file_style_list($variables) {
$styles = $variables['styles'];
$header = array(t('Style name'), t('Settings'), array('data' => t('Operations'), 'colspan' => 3));
$rows = array();
foreach ($styles as $style) {
$row = array();
$row[] = l($style['name'], 'admin/config/file/file-styles/edit/' . $style['name']);
$link_attributes = array(
'attributes' => array(
'class' => array('file-style-link'),
),
);
if ($style['storage'] == IMAGE_STORAGE_NORMAL) {
$row[] = t('Custom');
$row[] = l(t('edit'), 'admin/config/file/file-styles/edit/' . $style['name'], $link_attributes);
$row[] = l(t('delete'), 'admin/config/file/file-styles/delete/' . $style['name'], $link_attributes);
}
elseif ($style['storage'] == IMAGE_STORAGE_OVERRIDE) {
$row[] = t('Overridden');
$row[] = l(t('edit'), 'admin/config/file/file-styles/edit/' . $style['name'], $link_attributes);
$row[] = l(t('revert'), 'admin/config/file/file-styles/revert/' . $style['name'], $link_attributes);
}
else {
$row[] = t('Default');
$row[] = l(t('edit'), 'admin/config/file/file-styles/edit/' . $style['name'], $link_attributes);
$row[] = '';
}
$rows[] = $row;
}
if (empty($rows)) {
$rows[] = array(array(
'colspan' => 4,
'data' => t('There are currently no styles. <a href="!url">Add a new one</a>.', array('!url' => url('admin/config/file/file-styles/add'))),
));
}
return theme('table', array('header' => $header, 'rows' => $rows));
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* @file
* Functions needed to execute image effects provided by Image module.
*/
/**
* Implement hook_file_effect_info().
*/
function file_styles_file_effect_info() {
$effects = array(
'file_styles_image' => array(
'label' => t('Image styles'),
'styles' => array(),
'streams' => array('public://', 'private://'),
'mimetypes' => array('image/gif', 'image/jpeg', 'image/png'),
'module' => 'image',
'preview-theme' => 'image_style_preview',
'add-new-link' => l(t('Add new image style'), 'admin/config/file/image-styles/add'),
)
);
foreach (image_styles() as $style_name => $style) {
$effects['file_styles_image']['styles'][$style_name] = $style;
}
return $effects;
}

View File

@@ -0,0 +1,17 @@
name = File Styles
description = Allows preset transformation of files and media for display.
package = Styles
core = 7.x
files[] = file_styles.module
files[] = file_styles.admin.inc
files[] = includes/styles/FileStyles.inc
dependencies[] = styles
dependencies[] = image
; Information added by drupal.org packaging script on 2011-06-01
version = "7.x-2.0-alpha8"
core = "7.x"
project = "styles"
datestamp = "1306964517"

View File

@@ -0,0 +1,155 @@
<?php
/**
* @file styles/contrib/file_styles/file_styles.install
* Install, update and uninstall functions for the file styles module.
*/
/**
* Implement hook_install().
*/
function file_styles_install() {
// Create the styles directory and ensure it's writable.
$path = 'temporary://file-styles';
file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
}
/**
* Implement hook_uninstall().
*/
function file_styles_uninstall() {
// Remove the styles directory and generated images.
$path = 'temporary://file-styles';
file_unmanaged_delete_recursive($path);
}
/**
* Implement hook_schema().
*/
function file_styles_schema() {
$schema = array();
$schema['cache_file_styles'] = drupal_get_schema_unprocessed('system', 'cache');
$schema['cache_file_styles']['description'] = 'Cache table used to store information file manipulations that are in-progress.';
$schema['file_styles'] = array(
'description' => 'Stores configuration options for file styles.',
'fields' => array(
'msid' => array(
'description' => 'The primary identifier for a file style.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'name' => array(
'description' => 'The style name.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
),
'primary key' => array('msid'),
'indexes' => array(
'name' => array('name'),
),
);
$schema['file_effects'] = array(
'description' => 'Stores configuration options for file effects.',
'fields' => array(
'meid' => array(
'description' => 'The primary identifier for an file effect.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'msid' => array(
'description' => 'The {file_styles}.isid for a file style.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'weight' => array(
'description' => 'The weight of the effect in the style.',
'type' => 'int',
'unsigned' => FALSE,
'not null' => TRUE,
'default' => 0,
),
'name' => array(
'description' => 'The unique name of the effect to be executed.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'data' => array(
'description' => 'The configuration data for the effect.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
'serialize' => TRUE,
),
),
'primary key' => array('meid'),
'indexes' => array(
'msid' => array('msid'),
'weight' => array('weight'),
),
'foreign keys' => array(
'msid' => array('file_styles' => 'msid'),
),
);
return $schema;
}
/**
* Add labels to file styles.
*/
function file_styles_update_7202() {
return array();
}
/**
* Rebuild themes.
*/
function file_styles_update_7203() {
drupal_theme_rebuild();
return array();
}
/**
* Add new presets.
*/
function file_styles_update_7206() {
return array();
}
/**
* Fix presets to use camelCase and honor links to media.
*/
function file_styles_update_7207() {
return array();
}
/**
* Fetch any image styles for use as new presets and register new hooks.
*/
function file_styles_update_7208() {
return array();
}
/**
* Fix any broken custom image styles.
*/
function file_styles_update_7209() {
return array();
}
/**
* Add support for media objects.
*/
function file_styles_update_7210() {
return array();
}

View File

@@ -0,0 +1,169 @@
<?php
/**
* @file styles/contrib/file_styles/file_styles.module
* File widget formatter definitions.
*/
// A registry of variable_get defaults.
include_once('includes/file_styles.variables.inc');
/**
* Implementation of Styles module hook_styles_register().
*/
function file_styles_styles_register() {
return array(
'FileStyles' => array(
'field_types' => 'file',
'name' => t('file'),
'description' => t('file styles'),
'path' => drupal_get_path('module', 'file_styles') .'/includes/styles',
'file' => 'FileStyles.inc',
),
);
}
/**
* Styles filter callback.
*
* This will determine the correct style container corresponding to media type.
*/
function file_styles_styles_filter($object, $element = NULL) {
// Ensure we're working against the fully loaded file object.
$file = file_styles_uri_to_object($object->uri, TRUE);
// Allow other modules to define their own file styles.
// In general, they'll most likely want to check against the mimetype.
$containers = styles_default_containers('file');
$filters = module_invoke_all('file_styles_filter', $object);
foreach ($filters as $filter) {
if (isset($containers['containers'][$filter])) {
return $filter;
}
}
// Now check the part of the mimetype before the slash.
// Note that we can't use strstr($haystack, $needle, $before_needle)
// < PHP 5.3, so we need a work-around.
$filter = file_styles_strstr($object->filemime, '/', TRUE);
if (isset($containers['containers'][$filter])) {
return $filter;
}
// Fallback to default.
return 'default';
}
/**
* Support for strstr with $before_needle < PHP 5.3.
*/
function file_styles_strstr($haystack, $needle, $before_needle = FALSE){
if ($before_needle) {
list($var) = explode($needle, $haystack, 2);
return $var;
}
return strstr($haystack, $needle);
}
/**
* Return the path to the image for previews in Styles UI.
*
* If it doesn't yet exist, then copy the source to the files directory.
*
* @param boolean $replace
* If TRUE, then replace the file.
*
* @return mixed
* The path to the image preview file, or FALSE if unable to copy.
*/
function file_styles_preview_image($replace = FALSE) {
$path = file_styles_variable_get('preview_image');
if (!$path || $replace) {
$dir = file_default_scheme() . '://' . file_styles_variable_get('preview_image_directory');
if (file_prepare_directory($dir, FILE_CREATE_DIRECTORY)) {
$source = file_styles_variable_get('image_style_preview_image');
if ($path = file_unmanaged_copy($source, $dir . '/' . basename($source), FILE_EXISTS_REPLACE)) {
file_styles_variable_set('preview_image', $path);
}
}
}
return $path;
}
/**
* Implementation of hook_theme().
*/
function file_styles_theme($existing, $type, $theme, $path) {
return array(
'file_styles_image' => array(
'variables' => array('image_uri' => '', 'alt' => '', 'title' => '', 'attributes' => array(), 'image_style' => NULL, 'instance' => NULL),
'file' => 'file_styles.theme.inc',
'path' => $path . '/includes/themes',
),
'file_styles_image_preview' => array(
'variables' => array('style_name' => NULL),
'file' => 'file_styles.theme.inc',
'path' => $path . '/includes/themes',
),
);
}
/**
* Returns a file object which can be passed to file_save().
*
* @param $uri
* A string containing the URI, path, or filename.
* @param $use_existing
* (Optional) If TRUE and there's an existing file in the {file_managed}
* table with the passed in URI, then that file object is returned.
* Otherwise, a new file object is returned.
* @return
* A file object, or FALSE on error.
*
* @see http://drupal.org/node/685818
*/
function file_styles_uri_to_object($uri, $use_existing = FALSE) {
if ($use_existing) {
$query = db_select('file_managed', 'f')
->fields('f', array('fid'))
->condition('uri', $uri)
->execute()
->fetchCol();
if (!empty($query)) {
$file = file_load(array_shift($query));
}
}
if (!isset($file)) {
global $user;
$uri = file_stream_wrapper_uri_normalize($uri);
$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
$file = new StdClass;
$file->uid = $user->uid;
$file->filename = basename($uri);
$file->uri = $uri;
$file->filemime = file_get_mimetype($uri);
// This is gagged because some uris will not support it.
$file->filesize = @filesize($uri);
$file->timestamp = REQUEST_TIME;
$file->status = FILE_STATUS_PERMANENT;
$file->is_new = TRUE;
}
return $file;
}
/**
* Implements hook_image_style_save().
*/
function file_styles_image_style_save($image_style) {
// Rebuild the styles to account for any new image styles.
styles_style_flush();
}
/**
* Implements hook_image_style_delete().
*/
function file_styles_image_style_delete($image_style) {
// Rebuild the styles to account for any deleted image styles.
styles_style_flush();
}

View File

@@ -0,0 +1,165 @@
<?php
/**
* @file
* Theme functions for File styles.
*/
/**
* A wrapper for the image style preview.
*/
function theme_file_styles_image_style_preview($variables) {
$style_name = $variables['style_name'];
$styles = image_styles();
if (isset($styles[$style_name])) {
// The theme_image_style_preview function is in image.admin,
// but not properly referenced in hook_theme.
// @TODO: File a bug report and fix this in core.
module_load_include('inc', 'image', 'image.admin');
drupal_add_css(drupal_get_path('module', 'image') . '/image.admin.css');
// Ensure we revert the module & storage namespace for the Image module.
if (isset($styles[$style_name]['image_module'])) {
$styles[$style_name]['module'] = $styles[$style_name]['image_module'];
$styles[$style_name]['storage'] = $styles[$style_name]['image_storage'];
}
return theme('image_style_preview', array('style' => $styles[$style_name]));
}
}
function theme_file_styles_styles_default($variables) {
$file = $variables['object'];
$path = drupal_get_path('module', 'file');
$thumbnail = theme('image',
array(
'path' => $path . '/images/file-unknown.png',
'alt' => t('Thumbnail for !filename.', array('!filename' => $file->filename)),
'attributes' => array('width' => 100, 'height' => 75, 'class' => 'file-unknown'),
)
);
return $thumbnail;
}
function theme_file_styles_preview_default($variables) {
return 'default: theme_file_styles_preview_default';
}
function theme_file_styles_field_formatter_styles_default($variables) {
$file = $variables['object'];
$file_url = file_create_url($file->uri);
return l($file->filename, $file_url);
}
function theme_file_styles_field_formatter_styles($variables) {
// The formatter name needs to match what theme_field_formatter_image expects.
$variables['element']['#formatter'] = '__' . $variables['style']['name'];
// Add Alt & Title to the element.
$variables['element']['#item']['alt'] = $variables['element']['#item']['title'] = $variables['element']['#item']['description'];
// Defer to Image Styles for the rest.
return theme('field_formatter_image', $variables);
}
function theme_file_styles_image($variables) {
$file = $variables['object'];
$style_name = $variables['style_name'];
$vars = array();
$vars['path'] = $file->uri;
// Allow image attributes to be provided by the passed-in file object. 'alt'
// and 'title' need to be separated out because they are treated specially by
// theme_image().
if (isset($file->override)) {
$vars['attributes'] = $file->override;
foreach (array('alt', 'title') as $attribute) {
if (isset($vars['attributes'][$attribute])) {
$vars[$attribute] = $vars['attributes'][$attribute];
unset($vars['attributes'][$attribute]);
}
}
}
// Add default values for 'alt' and 'title'.
if (!isset($vars['alt'])) {
$vars['alt'] = isset($variables['description']) ? $variables['description'] : (isset($file->description) ? $file->description : '');
}
if (!isset($vars['title']) || $vars['title'] === '') {
$vars['title'] = isset($variables['title']) ? $variables['title'] : $vars['alt'];
}
// Special case for 'original'.
// @TODO Certainly can be more elegant than this.
if ($style_name == 'original') {
$vars['getsize'] = FALSE;
return theme('image', $vars);
}
$vars['style_name'] = $style_name;
//@TODO: How to add fields here?
return theme('image_style', $vars);
}
/**
* Support for HTML5 videos out of the box.
*/
function theme_file_styles_video($variables) {
$file = $variables['object'];
$style_name = $variables['style_name'];
$vars = array();
$width = isset($variables['width']) ? $variables['width'] : NULL;
$height = isset($variables['height']) ? $variables['height'] : NULL;
$path = file_create_url($file->uri);
$preset_name = $variables['preset_name'];
$preset = styles_containers_available_styles('file', 'video', $preset_name);
// By default, we don't display as a thumbnail.
$thumbnail = FALSE;
foreach ($preset['effects'] as $effect) {
switch ($effect['name']) {
case 'resize':
$width = isset($effect['data']['width']) ? $effect['data']['width'] : $width;
$height = isset($effect['data']['height']) ? $effect['data']['height'] : $height;
break;
case 'thumbnail':
$thumbnail = TRUE;
break;
}
}
if (isset($variables['object']->override)) {
$override = $variables['object']->override;
$width = isset($override['width']) ? $override['width'] : $width;
$height = isset($override['height']) ? $override['height'] : $height;
if (isset($override['wysiwyg']) && $override['wysiwyg']) {
$thumbnail = TRUE;
}
}
$vars['attributes'] = array('width' => $width, 'height' => $height);
if ($thumbnail) {
return theme('image', array('path' => drupal_get_path('module', 'file_styles') . '/images/file-video.png', 'attributes' => $vars['attributes'], 'getsize' => FALSE));
}
$width = isset($vars['attributes']['width']) ? ('width="' . $vars['attributes']['width'] . '"') : '';
$height = isset($vars['attributes']['height']) ? ('height="' . $vars['attributes']['height'] . '"') : '';
switch($file->filemime) {
case 'video/ogg':
$source = "<source src='$path' type='video/ogg; codecs=\"theora, vorbis\"'>";
break;
case 'video/mp4':
$source = "<source src='$path' type='video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'>";
break;
}
$output = "<video $width $height controls>$source</video>";
return $output;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,130 @@
<?php
/**
* @file file_styles/includes/file_styles.variables.inc
* Variable defaults for File Styles.
*/
/**
* Define our constants.
*/
/**
* This is the variable namespace, automatically prepended to module variables.
*/
define('FILE_STYLES_NAMESPACE', 'file_styles__');
/**
* Wrapper for variable_get() using the File Styles variable registry.
*
* @param string $name
* The variable name to retrieve. Note that it will be namespaced by
* pre-pending FILE_STYLES_NAMESPACE, as to avoid variable collisions
* with other modules.
* @param unknown $default
* An optional default variable to return if the variable hasn't been set
* yet. Note that within this module, all variables should already be set
* in the file_styles_variable_default() function.
* @return unknown
* Returns the stored variable or its default.
*
* @see file_styles_variable_set()
* @see file_styles_variable_del()
* @see file_styles_variable_default()
*/
function file_styles_variable_get($name, $default = NULL) {
// Allow for an override of the default.
// Useful when a variable is required (like $path), but namespacing is still
// desired.
if (!isset($default)) {
$default = file_styles_variable_default($name);
}
// Namespace all variables.
$variable_name = FILE_STYLES_NAMESPACE . $name;
return variable_get($variable_name, $default);
}
/**
* Wrapper for variable_set() using the File Styles variable registry.
*
* @param string $name
* The variable name to set. Note that it will be namespaced by
* pre-pending FILE_STYLES_NAMESPACE, as to avoid variable collisions with
* other modules.
* @param unknown $value
* The value for which to set the variable.
* @return unknown
* Returns the stored variable after setting.
*
* @see file_styles_variable_get()
* @see file_styles_variable_del()
* @see file_styles_variable_default()
*/
function file_styles_variable_set($name, $value) {
$variable_name = FILE_STYLES_NAMESPACE . $name;
return variable_set($variable_name, $value);
}
/**
* Wrapper for variable_del() using the File Styles variable registry.
*
* @param string $name
* The variable name to delete. Note that it will be namespaced by
* pre-pending FILE_STYLES_NAMESPACE, as to avoid variable collisions with
* other modules.
*
* @see file_styles_variable_get()
* @see file_styles_variable_set()
* @see file_styles_variable_default()
*/
function file_styles_variable_del($name) {
$variable_name = FILE_STYLES_NAMESPACE . $name;
variable_del($variable_name);
}
/**
* The default variables within the File Styles namespace.
*
* @param string $name
* Optional variable name to retrieve the default. Note that it has not yet
* been pre-pended with the FILE_STYLES_NAMESPACE namespace at this time.
* @return unknown
* The default value of this variable, if it's been set, or NULL, unless
* $name is NULL, in which case we return an array of all default values.
*
* @see file_styles_variable_get()
* @see file_styles_variable_set()
* @see file_styles_variable_del()
*/
function file_styles_variable_default($name = NULL) {
static $defaults;
if (!isset($defaults)) {
$defaults = array(
'image_style_preview_image' => variable_get('image_style_preview_image', drupal_get_path('module', 'image') . '/sample.png'),
'preview_image_directory' => 'file-styles',
'preview_image' => '',
);
}
if (!isset($name)) {
return $defaults;
}
if (isset($defaults[$name])) {
return $defaults[$name];
}
}
/**
* Return the fully namespace variable name.
*
* @param string $name
* The variable name to retrieve the namespaced name.
* @return string
* The fully namespace variable name, prepended with
* FILE_STYLES_NAMESPACE.
*/
function file_styles_variable_name($name) {
return FILE_STYLES_NAMESPACE . $name;
}

View File

@@ -0,0 +1,246 @@
<?php
/**
* @file styles/contrib/file_styles/includes/styles/FileStyles.inc
* Styles definitions for file styles.
*/
class FileStyles extends StylesDefault {
public $fid;
public $uri;
public $title;
public $alt;
public $width;
public $height;
public $float;
public $imagecachePreset = '';
public $link;
public $wrapperType = 'span';
public $classes = array('styles', 'file-styles');
public $streamWrapperInstance;
function getStreamWrapperInstance() {
$streamWrapperInstance = $this->get('stream_wrapper_instance');
if (!isset($streamWrapperInstance)) {
$streamWrapperInstance = $this->setStreamWrapperInstance(file_stream_wrapper_get_instance_by_uri($this->getUri()));
}
return $streamWrapperInstance;
}
function setStreamWrapperInstance($value) {
return $this->set('stream_wrapper_instance', $value);
}
function getFid() {
return $this->get('fid');
}
function setFid($value) {
return $this->set('fid', $value);
}
function setObject($value) {
$variables = $this->getVariables();
if (!isset($value->override) && isset($variables['entity']) && isset($variables['entity']->override)) {
$value->override = $variables['entity']->override;
}
return $this->set('object', $value);
}
function getUri() {
$uri = $this->get('uri');
if (isset($uri)) {
return $uri;
}
// If we don't have a URI yet, then try to find it from the object.
$object = $this->getObject();
if (isset($object->uri)) {
return $object->uri;
}
}
function setUri($value) {
return $this->set('uri', $value);
}
function getTitle() {
return $this->override('title');
}
function setTitle($value) {
// @TODO: Token support.
return $this->set('title', $value);
}
function getAlt() {
return $this->override('alt');
}
function setAlt($value) {
return $this->set('alt', $value);
}
function getWidth() {
return $this->override('width');
}
function setWidth($value) {
return $this->set('width', $value);
}
function getHeight() {
return $this->override('height');
}
function setHeight($value) {
return $this->set('height', $value);
}
function getImageStyle() {
return $this->get('imageStyle');
}
function setImageStyle($value) {
return $this->set('imageStyle', $value);
}
function getLink() {
return $this->get('link');
}
function setLink($value) {
return $this->set('link', $value);
}
function getFloat() {
return $this->override('float');
}
function setFloat($value) {
if ($value) {
$this->setPrefix('<span class="styles file-styles file-styles-float-'. filter_xss($value) .'">');
}
else {
$this->setPrefix('<span class="styles file-styles">');
}
return $this->set('float', $value);
}
function setImageUri($value) {
return $this->set('imageUri', $value);
}
function getImageUri() {
if ($imageUri = $this->get('imageUri')) {
return $imageUri;
}
return $this->getUri();
}
// Allow WYSIWYG to override the values.
public function override($attribute) {
$object = $this->getObject();
if (isset($object->override) && is_array($object->override) && isset($object->override[$attribute])) {
return $object->override[$attribute];
}
return $this->get($attribute);
}
// Effect callbacks when rendering.
function thumbnail($effect) {
$attributes = array();
$width = $this->getWidth();
$height = $this->getHeight();
if (isset($width)) {
$attributes['width'] = $width;
}
if (isset($height)) {
$attributes['height'] = $height;
}
// We have a .media-image class for WYSIWYG.
// We can't used ->getClass, because that's restricted.
$class = $this->override('class');
if (isset($class)) {
$attributes['class'] = $class;
}
// Set any WYSIWYG prescribed styles.
$style = $this->override('style');
$attributes['style'] = isset($style) ? ($style . ';') : '';
foreach (array('border-width', 'border-style', 'display', 'float', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left') as $property) {
$value = $this->override($property);
if (isset($value)) {
$attributes['style'] .= $property . ':' . $value . ';';
}
}
if ($attributes['style'] == '') {
unset($attributes['style']);
}
// Set any additional prescribed attributes.
// @todo Remove this as a hard-coded list. Note that not everything in
// $this->getObject()->override is an HTML attribute.
foreach (array('id', 'class', 'dir', 'lang') as $attribute) {
$value = $this->override($attribute);
if (!empty($value)) {
$attributes[$attribute] = $value;
}
}
if ($imageUri = $this->getImageUri()) {
$this->setOutput(theme('file_styles_image', array('image_uri' => $imageUri, 'attributes' => $attributes, 'alt' => $this->getAlt(), 'title' => $this->getTitle(), 'image_style' => $this->getImageStyle(), 'instance' => $this)));
// Honor any applied links.
if ($link = $this->getLink()) {
$this->setOutput(l($this->getOutput(), $link, array('html' => TRUE)));
}
}
}
function resize($effect) {
if (isset($effect['width'])) {
$this->setWidth($effect['width']);
}
if (isset($effect['height'])) {
$this->setHeight($effect['height']);
}
}
function float($effect) {
$this->setFloat($effect['float']);
}
function imageStyle($effect) {
$this->setImageStyle($effect['image_style']);
}
function linkToMedia($effect) {
// If we're using the media module, then link to its media page.
if (module_exists('media') && ($fid = $this->getFid())) {
$link = $this->setLink('media/'. $fid);
}
else {
// Link to the file's external url.
$uri = $this->getUri();
$stream_wrapper = file_stream_wrapper_get_instance_by_uri($uri);
$url = $stream_wrapper->getExternalUrl();
$link = $this->setLink($url);
}
if (!$this->getOutput() && ($title = $this->getTitle())) {
$this->setOutput(l($title, $link));
}
}
function linkToPath($effect) {
$link = $this->setLink($effect['path']);
if (!$this->getOutput() && $link && ($title = $this->getTitle())) {
$this->setOutput(l($title, $link));
}
}
function teaser($effect) {
$this->set('file', file_load($this->getFid()));
$this->setOutput(file_view($this->get('file')));
}
/**
* Override the render function to always display a thumbnail in the wysiwyg.
*/
public function render($reset = FALSE) {
$object = $this->getObject();
if (isset($object->override) && is_array($object->override) && isset($object->override['wysiwyg']) && $object->override['wysiwyg']) {
// Disregard any links pushed ahead.
$this->pushEffect(array('name' => 'linkToPath', 'settings' => array('path' => NULL)));
// We ensure that the thumbnail will be applied at the end.
$this->pushEffect(array('name' => 'thumbnail', 'settings' => array()));
}
return parent::render($reset);
}
}

View File

@@ -0,0 +1,215 @@
<?php
/**
* @file styles/contrib/file_styles/includes/styles/file_styles.styles.inc
* Implementations of various Styles hooks.
*/
/**
* Implementation of Styles module hook_styles_default_containers().
*/
function file_styles_styles_default_containers() {
$containers = array();
foreach (array('image', 'audio', 'video', 'default') as $type) {
$containers[$type] = array(
'label' => t(ucfirst($type)),
'class' => 'FileStyles',
);
}
$containers['image']['preview'] = 'file_styles_image_preview';
return array(
'file' => array(
'admin' => array(
'path' => 'admin/config/media/file-styles',
),
'filter callback' => 'file_styles_styles_filter',
'help' => t('Each of the following containers defines a set of styles that will be applied when a file is of the specified type. For instance, if a file field allows images and videos, a specific style might be defined for \'Thumbnail\', that will display a cropped image when a JPEG is given, or a thumbnail linking to a shadowboxed video when an MPEG is stored.'),
'containers' => $containers,
),
);
}
/**
* Implements hook_styles_default_containers().
*/
function file_styles_styles_default_containers_alter(&$styles) {
if (module_exists('media')) {
$styles['media'] = $styles['file'];
}
unset($styles['media']['admin']);
}
/**
* Implementation of Styles module hook_styles_default_styles().
*/
function file_styles_styles_default_styles() {
return array(
'file' => array(
'styles' => array(
'square_thumbnail' => array(
'label' => 'Square thumbnail',
'description' => 'A 120x120 square thumbnail for browsing media by an editor.',
),
'thumbnail' => array(
'label' => 'Thumbnail',
'description' => 'Small thumbnails representing the media.',
),
'large' => array(
'label' => 'Large',
'description' => 'A large format of the media.',
),
'medium' => array(
'label' => 'Medium',
'description' => 'A medium format of the media.',
),
'original' => array(
'label' => 'Original',
'description' => 'The original format of the media.',
),
),
),
);
}
/**
* Implements hook_styles_default_styles().
*/
function file_styles_styles_default_styles_alter(&$styles) {
if (module_exists('media')) {
$styles['media'] = $styles['file'];
}
}
/**
* Implementation of Styles module hook_styles_default_presets().
*/
function file_styles_styles_default_presets() {
$containers = array();
// @TODO: The real deal for video/audio/etc.
foreach (array('image', 'audio', 'video', 'default') as $type) {
$containers[$type] = array(
'default preset' => 'original',
'styles' => array(
'thumbnail' => array(
'default preset' => 'linked_thumbnail',
),
'square_thumbnail' => array(
'default preset' => 'linked_square_thumbnail',
),
'large' => array(
'default preset' => 'large',
),
'medium' => array(
'default preset' => 'medium',
),
),
'presets' => array(
'original' => array(
array(
'name' => 'thumbnail',
'settings' => array(),
)
),
'unlinked_thumbnail' => array(
array(
'name' => 'imageStyle',
'settings' => array(
'image_style' => 'thumbnail',
),
),
array(
'name' => 'thumbnail',
'settings' => array(),
),
),
'linked_thumbnail' => array(
array(
'name' => 'linkToMedia',
'settings' => array(),
),
array(
'name' => 'imageStyle',
'settings' => array(
'image_style' => 'thumbnail',
),
),
array(
'name' => 'thumbnail',
'settings' => array(),
),
),
'linked_square_thumbnail' => array(
array(
'name' => 'linkToMedia',
'settings' => array(),
),
array(
'name' => 'imageStyle',
'settings' => array(
'image_style' => 'square_thumbnail',
),
),
array(
'name' => 'thumbnail',
'settings' => array(),
),
),
'large' => array(
array(
'name' => 'imageStyle',
'settings' => array(
'image_style' => 'large',
),
),
array(
'name' => 'thumbnail',
'settings' => array(),
),
),
'medium' => array(
array(
'name' => 'imageStyle',
'settings' => array(
'image_style' => 'medium',
),
),
array(
'name' => 'thumbnail',
'settings' => array(),
),
),
),
);
}
foreach (image_styles() as $style_name => $style) {
if (!isset($containers['image']['presets'][$style_name])) {
$containers['image']['presets'][$style_name] = array(
array(
'name' => 'imageStyle',
'settings' => array(
'image_style' => $style_name,
),
),
array(
'name' => 'thumbnail',
'settings' => array(),
),
);
}
}
return array(
'file' => array(
'containers' => $containers,
),
);
}
/**
* Implements hook_styles_default_presets().
*/
function file_styles_styles_default_presets_alter(&$styles) {
if (module_exists('media')) {
$styles['media'] = $styles['file'];
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* @file file_styles/includes/themes/file_styles.theme.inc
*
* Theme and preprocess functions for the File Styles module.
*/
/**
* Display an image according to the style presented, or raw as specified.
*/
function theme_file_styles_image($variables) {
// @TODO: Check to see if the image is local as well, for getsize.
if (isset($variables['image_style'])) {
$output = theme('image_style', array('style_name' => $variables['image_style'], 'path' => $variables['image_uri'], 'alt' => $variables['alt'], 'title' => $variables['title'], 'getsize' => FALSE, 'attributes' => $variables['attributes']));
}
else {
$output = theme('image', array('path' => $variables['image_uri'], 'alt' => $variables['alt'], 'title' => $variables['title'], 'getsize' => FALSE, 'attributes' => $variables['attributes']));
}
return $output;
}
/**
* Preview image for Styles UI.
*/
function theme_file_styles_image_preview($variables) {
// Media requires a file object.
// Also, image_style_url() crashes if you send it a file from a module.
// Thus, we need to copy it to the public:// directory first, for styles
// that need to use an image style.
// @see http://drupal.org/node/987846#comment-3949112
$sample_image = file_styles_preview_image();
$variables['object'] = file_styles_uri_to_object($sample_image);
$variables['field_type'] = 'file';
return theme('styles', $variables);
}

View File

@@ -0,0 +1,2 @@
README for Styles UI

View File

@@ -0,0 +1,354 @@
<?php
/**
* @file
* Administrative page callbacks for the Styles UI module.
*/
/**
* Page callback for various styles overview listing pages.
*/
function styles_ui_containers_overview($field_type) {
// Get the full list of styles.
$styles = styles_default_styles();
// Get the containers for this field type.
$styles_containers = styles_default_containers();
$field_containers = $styles_containers[$field_type];
// Build our table listing of styles.
$header = array(t('Styles'), array('data' => t('Operations'), 'colspan' => 2));
$rows = array();
foreach ($styles[$field_type]['styles'] as $style_name => $style) {
// What's the path to edit this style?
$edit_path = $field_containers['admin']['path'] . '/edit/' . $style_name;
$row = array(l(t('@style', array('@style' => $style_name)), $edit_path));
// Add our ops.
if ($style['storage'] == STYLES_STORAGE_NORMAL) {
$row[] = array('data' => l(t('edit'), $edit_path));
$row[] = array('data' => l(t('delete'), $field_containers['admin']['path'] . '/delete/' . $style_name));
}
else if ($style['storage'] == STYLES_STORAGE_OVERRIDE) {
$row[] = array('data' => l(t('edit'), $edit_path));
$row[] = array('data' => l(t('revert'), $field_containers['admin']['path'] . '/delete/' . $style_name));
}
else {
$row[] = array('data' => l(t('edit'), $edit_path), 'colspan' => 2);
}
$rows[] = $row;
}
// Add a new style link to the empty table.
// Note that the link at the top of the page is placed in hook_menu.
$field_info = field_info_field_types($field_type);
$field_label = $field_info['label'];
$title = 'Add ' . $field_label . ' style';
$build['styles_table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('No styles available. <a href="@link">@add</a>.', array('@add' => t($title), '@link' => url($field_containers['admin']['path'] . '/add'))),
);
return $build;
}
/**
* Page callback for adding a style.
*/
function styles_ui_style_add_form($form, $form_state, $field_type) {
$form = array();
$form['field_type'] = array(
'#type' => 'value',
'#value' => $field_type,
);
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Style name'),
'#description' => t('Enter the name of your desired style, which must be a unique name containing only alphanumeric characters and underscores.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Validation handler for the add style form.
*/
function styles_ui_style_add_form_validate($form, $form_state) {
$field_type = $form_state['values']['field_type'];
$style_name = $form_state['values']['name'];
$styles = styles_default_styles();
if (!preg_match('!^[a-z0-9_]+$!', $style_name)) {
form_set_error('style_name', t('The machine-readable style name must contain only lowercase letters, numbers, and underscores.'));
}
else if (!empty($styles[$field_type]['styles'][$style_name])) {
form_set_error('style_name', t('The machine-readable style name %style_name is already taken.', array('%style_name' => $style_name)));
}
}
/**
* Submission handler for the add style form.
*/
function styles_ui_style_add_form_submit(&$form, &$form_state) {
$field_type = $form_state['values']['field_type'];
$style_name = $form_state['values']['name'];
$style = array(
'field_type' => $field_type,
'name' => $style_name,
'description' => '',
);
// Save the new style.
styles_style_save($style);
// Get the containers for this field type.
$styles_containers = styles_default_containers();
$field_containers = $styles_containers[$field_type];
// Redirect to this style's edit page.
$form_state['redirect'] = $field_containers['admin']['path'] . '/edit/' . $style_name;
}
/**
* Callback for the style edit form.
*/
function styles_ui_style_edit_form($form, $form_state, $field_type, $style_name) {
$style = styles_style_load($field_type, $style_name);
$form['field_type'] = array(
'#type' => 'value',
'#value' => $field_type,
);
$form['old_style_name'] = array(
'#type' => 'value',
'#value' => $style['name'],
);
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('The name of this style, which must be a unique name containing only alphanumeric characters and underscores.'),
'#default_value' => $style['name'],
'#required' => TRUE,
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#description' => t('The description of the style.'),
'#default_value' => $style['description'],
);
$form['containers'] = array(
'#type' => 'vertical_tabs',
'#tree' => TRUE,
);
$containers = styles_default_containers($field_type);
$presets = styles_default_presets($field_type);
foreach ($containers['containers'] as $container_name => $container) {
$style = $presets['containers'][$container_name]['styles'][$style_name];
$container_label = isset($container['label']) ? $container['label'] : $container_name;
$form['containers'][$container_name] = array(
'#type' => 'fieldset',
'#title' => t('@container', array('@container' => $container_label)),
);
$options = array();
foreach ($presets['containers'][$container_name]['presets'] as $preset_name => $preset) {
$options[$preset_name] = t('@preset', array('@preset' => $preset_name));
}
$default_value = isset($presets['containers'][$container_name]['styles'][$style_name]['preset']) ? $presets['containers'][$container_name]['styles'][$style_name]['preset'] : (isset($presets['containers'][$container_name]['styles'][$style_name]['default preset']) ? $presets['containers'][$container_name]['styles'][$style_name]['default preset'] : $presets['containers'][$container_name]['default preset']);
$form['containers'][$container_name]['preset'] = array(
'#type' => 'select',
'#title' => t('Preset'),
'#options' => $options,
'#default_value' => $default_value,
);
$form['containers'][$container_name]['default_preset'] = array(
'#type' => 'item',
'#title' => t('Default preset'),
'#markup' => t('%preset', array('%preset' => $style['default preset'])),
);
if (isset($container['preview'])) {
$form['containers'][$container_name]['preview'] = array(
'#type' => 'item',
'#title' => t('Preview'),
'#markup' => theme($container['preview'], array('style_name' => $style_name)),
);
}
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
// $field_info = field_info_field_types($field_type);
// $presets = styles_default_presets();
// $preset = $presets[$field_type]['containers'][$preset_name];
// $styles_containers = styles_default_containers();
// $containers = $styles_containers[$field_type]['containers'];
// drupal_set_title(t('Edit @field_type style preset: @preset', array('@field_type' => $field_info['label'], '@preset' => $preset_name)));
// $form = array();
// $form['containers'] = array(
// '#type' => 'vertical_tabs',
// );
// $styles = styles_default_styles($field_type);
// dpm($styles);
//
// // Begin the settings array to send to jQuery.
// $settings = array(
// 'stylesUI' => array(
// 'url' => url('styles-ui/preview'),
// 'fieldType' => check_plain($field_type),
// ),
// );
// foreach ($styles['styles'] as $style_name => $style) {
// $form['containers'][$style_name] = array(
// '#type' => 'fieldset',
// '#title' => $style['label'],
// );
// if (isset($preset['styles'][$style_name]['current preset'])) {
// $this_preset = $preset['styles'][$style_name]['current preset'];
// }
// else {
// $this_preset = $preset['styles'][$style_name]['default preset'];
// }
// $options = array();
// foreach ($preset['presets'] as $preset_style_name => $effects) {
// $options[$preset_style_name] = $preset_style_name;
// }
//
// // Store the container in the 'rel' attribute for later AJAX previews.
// $rel = check_plain($style_name);
// $form['containers'][$style_name]['preset_' . $style_name] = array(
// '#type' => 'radios',
// '#title' => t('Style effects preset'),
// '#default_value' => $this_preset,
// '#options' => $options,
// '#attributes' => array('class' => array('styles-ui-preset'), 'rel' => $rel),
// );
// // Add a preview.
// if (isset($styles_containers[$field_type]['themes']) && isset($styles_containers[$field_type]['themes']['preview'])) {
// $preview = '<div id="styles-ui-preview-wrapper-' . $rel . '" class="styles-ui-preview-wrapper">' . theme($styles_containers[$field_type]['themes']['preview'], array('field_type' => $field_type, 'container_name' => $style_name, 'style_name' => $this_preset)) . '</div>';
// $form['containers'][$style_name]['preview_' . $style_name] = array(
// '#type' => 'item',
// '#title' => t('Style preview'),
// '#markup' => $preview,
// );
// }
// }
// // Add the javascript for live previews on radio select.
// $form['#attached'] = array(
// 'js' => array(drupal_get_path('module', 'styles_ui') . '/styles_ui.js'),
// );
// drupal_add_js($settings, array('type' => 'setting'));
// return $form;
}
/**
* Validation handler for the edit style form.
*/
function styles_ui_style_edit_form_validate($form, $form_state) {
$field_type = $form_state['values']['field_type'];
$style_name = $form_state['values']['name'];
$old_style_name = $form_state['values']['old_style_name'];
$styles = styles_default_styles();
if (!preg_match('!^[a-z0-9_]+$!', $style_name)) {
form_set_error('style_name', t('The machine-readable style name must contain only lowercase letters, numbers, and underscores.'));
}
else if (($style_name != $old_style_name) && !empty($styles[$field_type]['styles'][$style_name])) {
form_set_error('style_name', t('The machine-readable style name %style_name is already taken.', array('%style_name' => $style_name)));
}
}
/**
* Submission handler for the add style form.
*/
function styles_ui_style_edit_form_submit(&$form, &$form_state) {
$field_type = $form_state['values']['field_type'];
$style_name = $form_state['values']['name'];
$style = array(
'field_type' => $field_type,
'name' => $style_name,
'description' => $form_state['values']['description'],
);
// Save the new style.
styles_style_save($style);
// Get the containers for this field type.
$styles = styles_default_presets($field_type);
$containers = styles_default_containers($field_type);
foreach ($form_state['values']['containers'] as $container_name => $container) {
if (is_array($container)) {
$default_preset = isset($styles['containers'][$container_name]['styles'][$style_name]['default preset']) ? $styles['containers'][$container_name]['styles'][$style_name]['default preset'] : $styles['containers'][$container_name]['default preset'];
$delete_only = ($default_preset == $container['preset']);
styles_style_save_preset($field_type, $container_name, $style_name, $container['preset'], $delete_only);
}
}
// Redirect to this style's edit page.
$form_state['redirect'] = $containers['admin']['path'] . '/edit/' . $style_name;
}
function styles_ui_preview_ajax($field_type, $container_name, $preset_name) {
$styles_containers = styles_default_containers();
$containers = $styles_containers[$field_type]['containers'];
drupal_json_output(array(
'id' => '#styles-ui-preview-wrapper-' . check_plain($container_name),
'preview' => theme($containers[$container_name]['themes']['preview'], array('field_type' => $field_type, 'container_name' => $container_name, 'style_name' => $preset_name)),
));
die();
}
/**
* Menu callback; delete a style.
*/
function styles_ui_delete_confirm($form, &$form_state, $field_type, $style_name) {
$form['field_type'] = array(
'#type' => 'value',
'#value' => $field_type,
);
$form['style_name'] = array(
'#type' => 'value',
'#value' => $style_name,
);
$styles = styles_default_styles($field_type);
$style = $styles['styles'][$style_name];
if ($style['storage'] == STYLES_STORAGE_OVERRIDE) {
$delete = 'revert';
}
else {
$delete = 'delete';
}
$caption = '<p>' . t('This action cannot be undone.') . '</p>';
$containers = styles_default_containers($field_type);
$cancel_path = $containers['admin']['path'];
$form['containers'] = array(
'#type' => 'value',
'#value' => $containers,
);
$message = t('Are you sure you want to @delete the %field_type style %style_name?', array('@delete' => $delete, '%field_type' => $field_type, '%style_name' => $style_name));
return confirm_form($form, $message, $cancel_path, $caption, t('@delete', array('@delete' => ucfirst($delete))));
}
/**
* Process style delete confirm submissions.
*/
function styles_ui_delete_confirm_submit($form, &$form_state) {
$field_type = $form_state['values']['field_type'];
$style_name = $form_state['values']['style_name'];
$containers = styles_default_containers($field_type);
styles_style_delete($field_type, $style_name);
// Redirect to this style's edit page.
$form_state['redirect'] = $containers['admin']['path'];
}

View File

@@ -0,0 +1,14 @@
name = Styles UI
description = Allows administration of the Styles modules.
package = Styles
core = 7.x
files[] = styles_ui.admin.inc
dependencies[] = styles
; Information added by drupal.org packaging script on 2011-06-01
version = "7.x-2.0-alpha8"
core = "7.x"
project = "styles"
datestamp = "1306964517"

View File

@@ -0,0 +1,44 @@
<?php
/**
* @file styles/contrib/styles_ui/styles_ui.install
* Install, update and uninstall functions for the Styles module.
*/
/**
* Implement hook_install().
*/
function styles_ui_install() {
return array();
}
/**
* Implement hook_uninstall().
*/
function styles_ui_uninstall() {
return array();
}
/**
* Rebuild styles.
*/
function styles_ui_update_7200() {
cache_clear_all('styles_', 'cache', TRUE);
return array();
}
/**
* Change themes.
*/
function styles_ui_update_7201() {
drupal_theme_rebuild();
return array();
}
/**
* Change menu.
*/
function styles_ui_update_7206() {
menu_rebuild();
return array();
}

View File

@@ -0,0 +1,27 @@
/**
* @file
* jQuery attachment to Styles UI admin pages.
*/
(function ($) {
/**
* Change the preview on radio change.
*/
Drupal.behaviors.stylesUI = {
attach: function(context, settings) {
$('.styles-ui-preset', context).once('stylesUI', function () {
$(this).bind('change', function() {
$preset = $(this);
if ($preset.val()) {
$.getJSON(Drupal.settings.stylesUI.url + '/' + Drupal.settings.stylesUI.fieldType + '/' + $preset.attr('rel') + '/' + $preset.val(), function(data){
// @TODO: Check for errors.
$(data.id).html(data.preview);
});
}
});
});
}
}
// end of closure
})(jQuery);

View File

@@ -0,0 +1,102 @@
<?php
/**
* @file
* Allows administration of the Styles modules.
*/
/**
* Implements hook_menu().
*/
function styles_ui_menu() {
// Each field type Style may choose to allow the Styles module to manage its
// UI. To do so, they'll need to create an 'admin' array in its definition
// at hook_styles_containers that will contain the path info:
// 'path' => The path to the overview listing page,
// 'title' => The title for the overview listing page,
// 'description' => The description for the overview listing page,
// 'access arguments' => The access arguments for the overview listing page,
// 'add' => an optional array with the info for adding a new container:
// 'title' => The title to add a new container for this field,
// 'description' => The discription to add a new container for this field,
$items = array();
$styles_containers = styles_default_containers();
foreach ($styles_containers as $field_type => $containers) {
if (isset($containers['admin']) && isset($containers['admin']['path'])) {
$field_info = field_info_field_types($field_type);
$field_label = $field_info['label'];
$title = $field_label . ' styles';
$description = 'Configure ' . $field_label . ' styles.';
$access = isset($containers['admin']['access arguments']) ? $containers['admin']['access arguments'] : array('administer styles ui');
$items[$containers['admin']['path']] = array(
'title' => $title,
'description' => $description,
'access arguments' => $access,
'page callback' => 'styles_ui_containers_overview',
'page arguments' => array($field_type),
'file' => 'styles_ui.admin.inc',
);
$items[$containers['admin']['path'] . '/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$title = 'Add ' . $field_label . ' style';
$description = '';
$items[$containers['admin']['path'] . '/add'] = array(
'title' => $title,
'description' => $description,
'page callback' => 'drupal_get_form',
'page arguments' => array('styles_ui_style_add_form', $field_type),
'access arguments' => $access,
'type' => MENU_LOCAL_ACTION,
'file' => 'styles_ui.admin.inc',
);
$count = substr_count($containers['admin']['path'] . '/edit/%', '/');
$items[$containers['admin']['path'] . '/edit/%'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('styles_ui_style_edit_form', $field_type, $count),
'access arguments' => $access,
'file' => 'styles_ui.admin.inc',
);
$items[$containers['admin']['path'] . '/delete/%'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('styles_ui_delete_confirm', $field_type, $count),
'access arguments' => $access,
'file' => 'styles_ui.admin.inc',
);
}
}
$items['styles-ui/preview/%/%/%'] = array(
'page callback' => 'styles_ui_preview_ajax',
'page arguments' => array(2, 3, 4),
'access arguments' => array('access content'),
'file' => 'styles_ui.admin.inc',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implement Styles module's hook_styles_style_flush().
*/
function styles_ui_styles_style_flush($style = NULL) {
// Rebuild the menu so that we catch any new styles or containers.
menu_rebuild();
}
/**
* Implementation of hook_permission().
*/
function styles_ui_permission() {
return array(
'administer styles ui' => array(
'title' => t('Administer Styles'),
'description' => t('Configure styles settings.'),
),
);
}

View File

@@ -0,0 +1,308 @@
<?php
/**
* @file Styles.inc
* Base class for Styles.
*/
class StylesDefault {
// The variables passed from our theme.
public $variables = array();
// The object passed from our theme.
public $object = array();
// Any effects to apply when displaying content matching this style.
public $effects = array();
// The final rendered output for this item.
public $output;
public $prefix;
public $suffix;
public $wrapperType = 'div';
public $classes = array('styles');
public $id;
private $_id = 0;
public function __construct($object = NULL, $effects = NULL, $variables = NULL) {
// @TODO: This is not great IMO, the ->object and ->variables props already have everything
// we shouldn't be duplicating it in different methods / properties.
if (isset($variables)) {
$properties = (array) $variables;
$this->magicSet($properties);
$this->setVariables($variables);
}
// If we are passed an array, then set the object properties from its keys.
if (isset($object)) {
$properties = (array) $object;
$this->magicSet($properties);
$this->setObject($object);
}
if (isset($effects)) {
$this->setEffects($effects);
}
}
/**
* Converts a string in the form with_underscores to withUnderscores
* @param string $str
* @return string
*/
protected function _toCamelCase($str) {
$parts = explode("_", $str);
$out = array_shift($parts);
foreach ($parts as $part) {
$out .= ucfirst($part);
}
return $out;
}
/**
* Given an array of k/v pairs calls set$key
* @param array $properties
*/
protected function magicSet($properties) {
$methods = get_class_methods($this);
foreach ($properties as $key => $value) {
$propName = "set_{$key}";
$function = $this->_toCamelCase($propName);
if (in_array($function, $methods)) {
$this->$function($value);
}
}
}
/**
* Display the rendered output.
*
* @param boolean $reset
* Optional; if TRUE, the rebuild the output.
* @return
* A fully themed snippet of HTML for output.
*/
public function display($reset = FALSE) {
return $this->render($reset);
}
/**
* Build the output for display.
*
* @param boolean $reset
* Optional; if TRUE, the rebuild the output.
* @return
* A fully themed snippet of HTML for output.
*/
public function render($reset = FALSE) {
// If we need to reset, then set the output to NULL.
if ($reset) {
$this->setOutput(NULL);
}
// Have we already rendered the output?
$output = $this->getOutput();
// We need to render the output the first time around, or if reset.
if (!isset($output)) {
// First, we get the array of callable class methods for this object.
// These may each be called by effects called for by the style.
// @TODO: Should we have a proper array of allowable effects, rather
// than our current lazy method of allowing all class functions?
$methods = get_class_methods($this);
// Loop through and apply each effect.
foreach ($this->getEffects() as $effect) {
// What is the effect?
$effectName = $effect['name'];
if ($effectName && in_array($effectName, $methods)) {
// Apply the effect with its settings.
$this->$effectName($effect['settings']);
}
else {
// Ouch. We have an invalid effect. Flag for bug reporting.
$variables = $this->getVariables();
$styleName = $variables['style']['name'];
watchdog('styles', 'Effect %effect_name not found for %style_name display formatter style of the %class_name class.', array('%effect_name' => $effectName, '%style_name' => $styleName, '%class_name' => $this->getClassName()), WATCHDOG_WARNING);
}
}
// Now the output will have been fully built.
$output = $this->getOutput();
}
return $output;
}
public function getClassName() {
return get_called_class();
}
public function _get($variable) {
if (function_exists('get_' . $variable)) {
return $this->{'get_' . $variable}();
}
else {
return $this->get($variable);
}
}
public function _set($variable, $value) {
if (function_exists('set_' . $variable)) {
return $this->{'set_' . $variable}($value);
}
else {
return $this->set($variable, $value);
}
}
public function arrayPush($variable, $element) {
$array = (array) $this->_get($variable);
array_push($array, $element);
return $this->_set($variable, $array);
}
public function arrayPop($variable) {
$array = (array) $this->_get($variable);
array_pop($array);
return $this->_set($variable, $array);
}
public function arrayUnshift($variable, $element) {
$array = (array) $this->_get($variable);
array_unshift($array, $element);
return $this->_set($variable, $array);
}
public function arrayShift($variable) {
$array = (array) $this->_get($variable);
array_shift($array);
return $this->_set($variable, $array);
}
/**
* Add an effect to the end of the array.
*
* An effect is an array with at least a 'name' key, which corresponds to the
* class function to be called during the rendering process. It will usually
* also contain an array of 'effects' to apply.
*/
public function addEffect($effect) {
return $this->pushEffect($effect);
}
public function pushEffect($effect) {
$effectName = $effect['name'];
if (method_exists($this, $effectName)) {
$effects = $this->getEffects();
array_push($effects, $effect);
return $this->setEffects($effects);
}
else {
$variables = $this->getVariables();
$styleName = $variables['style']['label'];
watchdog('styles', 'Effect %effect_name not found for %style_name display formatter style of the %class_name class.', array('%effect_name' => $effectName, '%style_name' => $styleName, '%class_name' => $this->getClassName()), WATCHDOG_WARNING);
}
}
public function popEffect() {
$effects = $this->getEffects();
$effect = array_pop($effects);
$this->setEffects($effects);
return $effect;
}
public function unshiftEffect($effect) {
$effectName = $effect['name'];
if (method_exists($this, $effectName)) {
$effects = $this->getEffects();
array_unshift($effects, $effect);
return $this->setEffects($effects);
}
else {
$variables = $this->getVariables();
$styleName = $variables['style']['label'];
watchdog('styles', 'Effect %effect_name not found for %style_name display formatter style of the %class_name class.', array('%effect_name' => $effectName, '%style_name' => $this->getName(), '%class_name' => $this->getClassName()), WATCHDOG_WARNING);
}
}
public function shiftEffect() {
$effects = $this->getEffects();
$effect = array_shift($effects);
$this->setEffects($effects);
return $effect;
}
public function getObject() {
return $this->get('object');
}
public function setObject($value) {
return $this->set('object', $value);
}
public function getVariables() {
return $this->get('variables');
}
public function setVariables($value) {
return $this->set('variables', $value);
}
public function getEffects() {
return $this->get('effects');
}
public function setEffects($value) {
return $this->set('effects', $value);
}
public function getWrapperType() {
return $this->get('wrapperType');
}
public function setWrapperType($value) {
return $this->set('wrapperType', $value);
}
public function getClasses() {
$classes = $this->get('classes');
return is_array($classes) ? implode(' ', $classes) : $classes;
}
public function setClasses($value) {
return $this->set('classes', $value);
}
public function getId() {
return $this->get('id');
}
public function setId($value) {
return $this->set('id', $value);
}
public function getOutput() {
return $this->get('output');
}
public function setOutput($value) {
return $this->set('output', $value);
}
public function getPrefix() {
$prefix = $this->get('prefix');
if (!isset($prefix)) {
$wrapperType = $this->getWrapperType();
$id = $this->getId();
$_id = $this->_id++;
$classes = $this->getClasses();
$prefix = "<$wrapperType id=\"styles-$id-$_id\" class=\"$classes\">";
}
return $prefix;
}
public function setPrefix($value) {
return $this->set('prefix', $value);
}
public function getSuffix() {
$suffix = $this->get('suffix');
if (!isset($suffix)) {
$wrapperType = $this->getWrapperType();
$suffix = "</$wrapperType>";
}
return $suffix;
}
public function setSuffix($value) {
return $this->set('suffix', $value);
}
public function get($variable) {
return isset($this->{$variable}) ? $this->{$variable} : NULL;
}
public function set($variable, $value) {
return $this->{$variable} = $value;
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* @file
*
* Add support for get_called_class() to < PHP 5.3.
*
* @see http://www.php.net/manual/en/function.get-called-class.php#93799
*/
/********************************
* Retro-support of get_called_class()
* Tested and works in PHP 5.2.4
* http://www.sol1.com.au/
********************************/
if(!function_exists('get_called_class')) {
function get_called_class($bt = false,$l = 1) {
if (!$bt) $bt = debug_backtrace();
if (!isset($bt[$l])) throw new Exception("Cannot find called class -> stack level too deep.");
if (!isset($bt[$l]['type'])) {
throw new Exception ('type not set');
}
else switch ($bt[$l]['type']) {
case '::':
$lines = file($bt[$l]['file']);
$i = 0;
$callerLine = '';
do {
$i++;
$callerLine = $lines[$bt[$l]['line']-$i] . $callerLine;
} while (stripos($callerLine,$bt[$l]['function']) === false);
preg_match('/([a-zA-Z0-9\_]+)::'.$bt[$l]['function'].'/',
$callerLine,
$matches);
if (!isset($matches[1])) {
// must be an edge case.
throw new Exception ("Could not find caller class: originating method call is obscured.");
}
switch ($matches[1]) {
case 'self':
case 'parent':
return get_called_class($bt,$l+1);
default:
return $matches[1];
}
// won't get here.
case '->': switch ($bt[$l]['function']) {
case '__get':
// edge case -> get class of calling object
if (!is_object($bt[$l]['object'])) throw new Exception ("Edge case fail. __get called on non object.");
return get_class($bt[$l]['object']);
default: return $bt[$l]['class'];
}
default: throw new Exception ("Unknown backtrace method type");
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* @file
* Hooks available for modules to implement Styles functionality.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Define information about style containers provided by a module.
*
* This hook enables modules to define style containers provided by this module.
*
* @return
* An array of available style containers.Each container is defined as an
* array keyed by the field type, each containing an associative array keyed
* on a machine-readable style container name, with the following items:
* - "label": The human-readable name of the effect.
* - "data": An array of data that each container might require.
* - "preview theme": (optional) A theme function to call when previewing
* a style during administration.
* - "help": (optional) A brief description of the style container that will
* be displayed to the administrator when configuring styles.
*/
function hook_styles_containers() {
return array(
'media' => array(
'image' => array(
'label' => t('Image Styles'),
'data' => array(
'streams' => array(
'public://',
'private://',
),
'mimetypes' => array(
'image/png',
'image/gif',
'image/jpeg',
),
),
'preview theme' => 'media_styles_image_style_preview',
'help' => t('Image Styles will transform images to your choosing, such as by scaling and cropping. You can !manage.', array('!manage' => l(t('manage your image styles here'), 'admin/config/image/image-styles'))),
),
),
);
}
function hook_styles_styles() {
$styles = array();
foreach (image_styles() as $style_name => $style) {
$styles[$style_name] = $style;
}
return array(
'media' => array(
'image' => $styles,
),
);
}

View File

@@ -0,0 +1,152 @@
<?php
/**
* @file styles.variables.inc
* Variable defaults for Styles.
*/
/**
* Define our constants.
*/
/**
* This is the variable namespace, automatically prepended to module variables.
*/
define('STYLES_NAMESPACE', 'styles__');
/**
* Styles constant for user styles in the database.
*/
define('STYLES_STORAGE_NORMAL', 1);
/**
* Styles constant for user styles that override module-defined styles.
*/
define('STYLES_STORAGE_OVERRIDE', 2);
/**
* Styles constant for module-defined styles in code.
*/
define('STYLES_STORAGE_DEFAULT', 4);
/**
* Styles constant to represent an editable preset.
*/
define('STYLES_STORAGE_EDITABLE', STYLES_STORAGE_NORMAL | STYLES_STORAGE_OVERRIDE);
/**
* Styles constant to represent any module-based preset.
*/
define('STYLES_STORAGE_MODULE', STYLES_STORAGE_OVERRIDE | STYLES_STORAGE_DEFAULT);
/**
* Wrapper for variable_get() using the Styles variable registry.
*
* @param string $name
* The variable name to retrieve. Note that it will be namespaced by
* pre-pending STYLES_NAMESPACE, as to avoid variable collisions
* with other modules.
* @param unknown $default
* An optional default variable to return if the variable hasn't been set
* yet. Note that within this module, all variables should already be set
* in the styles_variable_default() function.
* @return unknown
* Returns the stored variable or its default.
*
* @see styles_variable_set()
* @see styles_variable_del()
* @see styles_variable_default()
*/
function styles_variable_get($name, $default = NULL) {
// Allow for an override of the default.
// Useful when a variable is required (like $path), but namespacing is still
// desired.
if (!isset($default)) {
$default = styles_variable_default($name);
}
// Namespace all variables.
$variable_name = STYLES_NAMESPACE . $name;
return variable_get($variable_name, $default);
}
/**
* Wrapper for variable_set() using the Styles variable registry.
*
* @param string $name
* The variable name to set. Note that it will be namespaced by
* pre-pending STYLES_NAMESPACE, as to avoid variable collisions with
* other modules.
* @param unknown $value
* The value for which to set the variable.
* @return unknown
* Returns the stored variable after setting.
*
* @see styles_variable_get()
* @see styles_variable_del()
* @see styles_variable_default()
*/
function styles_variable_set($name, $value) {
$variable_name = STYLES_NAMESPACE . $name;
return variable_set($variable_name, $value);
}
/**
* Wrapper for variable_del() using the Styles variable registry.
*
* @param string $name
* The variable name to delete. Note that it will be namespaced by
* pre-pending STYLES_NAMESPACE, as to avoid variable collisions with
* other modules.
*
* @see styles_variable_get()
* @see styles_variable_set()
* @see styles_variable_default()
*/
function styles_variable_del($name) {
$variable_name = STYLES_NAMESPACE . $name;
variable_del($variable_name);
}
/**
* The default variables within the Styles namespace.
*
* @param string $name
* Optional variable name to retrieve the default. Note that it has not yet
* been pre-pended with the STYLES_NAMESPACE namespace at this time.
* @return unknown
* The default value of this variable, if it's been set, or NULL, unless
* $name is NULL, in which case we return an array of all default values.
*
* @see styles_variable_get()
* @see styles_variable_set()
* @see styles_variable_del()
*/
function styles_variable_default($name = NULL) {
static $defaults;
if (!isset($defaults)) {
$defaults = array(
);
}
if (!isset($name)) {
return $defaults;
}
if (isset($defaults[$name])) {
return $defaults[$name];
}
}
/**
* Return the fully namespace variable name.
*
* @param string $name
* The variable name to retrieve the namespaced name.
* @return string
* The fully namespace variable name, prepended with
* STYLES_NAMESPACE.
*/
function styles_variable_name($name) {
return STYLES_NAMESPACE . $name;
}

View File

@@ -0,0 +1,14 @@
name = Styles
description = Bundles similar display formatters together.
package = Styles
core = 7.x
files[] = styles.module
files[] = includes/Styles.inc
; Information added by drupal.org packaging script on 2011-06-01
version = "7.x-2.0-alpha8"
core = "7.x"
project = "styles"
datestamp = "1306964517"

View File

@@ -0,0 +1,370 @@
<?php
/**
* @file
* Install, update and uninstall functions for the Styles module.
*/
/**
* Implement hook_install().
*/
function styles_install() {
return array();
}
/**
* Implement hook_uninstall().
*/
function styles_uninstall() {
foreach (styles_variable_default() as $variable => $value) {
styles_variable_del($variable);
}
return array(array('success' => TRUE, 'query' => "Deleted all variables in the Styles namespace."));
}
/**
* Implement hook_schema().
*/
function styles_schema() {
$schema = array();
$schema['cache_styles'] = drupal_get_schema_unprocessed('system', 'cache');
$schema['cache_styles']['description'] = 'Cache table used to store information display manipulations that are in-progress.';
$schema['styles'] = array(
'description' => 'Stores configuration options for styles.',
'fields' => array(
'sid' => array(
'description' => 'The primary identifier for a style.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'field_type' => array(
'description' => 'The field type.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'name' => array(
'description' => 'The style name.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'description' => array(
'description' => 'The style description.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
),
),
'primary key' => array('sid'),
'indexes' => array(
'field_type' => array('field_type'),
'name' => array('name'),
),
);
$schema['styles_presets'] = array(
'description' => 'Stores configuration options for styles presets.',
'fields' => array(
'pid' => array(
'description' => 'The primary identifier for a style preset.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'field_type' => array(
'description' => 'The field type.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'container_name' => array(
'description' => 'The container name',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'name' => array(
'description' => 'The preset name.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
),
'primary key' => array('pid'),
'indexes' => array(
'field_type' => array('field_type'),
'container_name' => array('container_name'),
'name' => array('name'),
),
);
$schema['styles_preset_instances'] = array(
'description' => 'Stores the settings for each container/style preset.',
'fields' => array(
'sid' => array(
'description' => 'The primary identifier for a style.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'pid' => array(
'description' => 'The primary identifier for a style preset.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'foreign keys' => array(
'sid' => array(
'table' => 'styles',
'columns' => array('sid' => 'sid'),
),
'pid' => array(
'table' => 'styles_presets',
'columns' => array('pid' => 'pid'),
),
),
'indexes' => array(
'sid' => array('sid'),
'pid' => array('pid'),
),
);
return $schema;
}
/**
* Add new theme functions.
*/
function styles_update_7200() {
drupal_theme_rebuild();
return array();
}
/**
* Clear old cache table of any styles data.
*/
function styles_update_7201() {
cache_clear_all('styles_', 'cache', TRUE);
return array();
}
/**
* Add the field_type column to the {styles} table.
*/
function styles_update_7202() {
db_add_field('styles', 'field_type', array(
'description' => 'The field type.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
));
db_add_index('styles', 'field_type', array('field_type'));
}
/**
* Add the label & description columns to the {styles} table.
*/
function styles_update_7204() {
db_add_field('styles', 'label', array(
'description' => 'The human readable label for the style.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
));
db_add_field('styles', 'description', array(
'description' => 'The style description.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
));
db_add_index('styles', 'label', array('label'));
}
/**
* Drop the label column from the {styles} table; alter the description column.
*/
function styles_update_7206() {
db_drop_field('styles', 'label');
db_drop_index('styles', 'label');
db_change_field('styles', 'description', 'description',
array(
'description' => 'The style description.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
)
);
}
/**
* Clear style and preset caches.
*/
function styles_update_7208() {
return array();
}
/**
* Ensure we catch included file Styles.inc.
*/
function styles_update_7209() {
return array();
}
/**
* Drop style_effects table.
*/
function styles_update_7211() {
db_drop_table('style_effects');
}
/**
* Create the styles_presets and styles_preset_instances tables.
*/
function styles_update_7212() {
$schema = array();
$schema['styles_presets'] = array(
'description' => 'Stores configuration options for styles presets.',
'fields' => array(
'pid' => array(
'description' => 'The primary identifier for a style preset.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'field_type' => array(
'description' => 'The field type.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'container_name' => array(
'description' => 'The container name',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'name' => array(
'description' => 'The preset name.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
),
'description' => array(
'description' => 'The preset description.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
),
),
'primary key' => array('pid'),
'indexes' => array(
'field_type' => array('field_type'),
'container_name' => array('container_name'),
'name' => array('name'),
),
);
$schema['styles_preset_instances'] = array(
'description' => 'Stores the settings for each container/style preset.',
'fields' => array(
'sid' => array(
'description' => 'The primary identifier for a style.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'pid' => array(
'description' => 'The primary identifier for a style preset.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'foreign keys' => array(
'sid' => array(
'table' => 'styles',
'columns' => array('sid' => 'sid'),
),
'pid' => array(
'table' => 'styles_presets',
'columns' => array('pid' => 'pid'),
),
),
'indexes' => array(
'sid' => array('sid'),
'pid' => array('pid'),
),
);
if (!db_table_exists('styles_presets')) {
db_create_table('styles_presets', $schema['styles_presets']);
}
if (!db_table_exists('styles_preset_instances')) {
db_create_table('styles_preset_instances', $schema['styles_preset_instances']);
}
}
/**
* Remove the description from styles_presets.
*/
function styles_update_7213() {
db_drop_field('styles_presets', 'description');
}
/**
* Update old File Style formatters on Image fields to the Image formatter.
*/
function styles_update_7214() {
$instances = array();
$fields = field_read_fields(array('type' => 'image'), array('include_inactive' => TRUE));
foreach ($fields as $field) {
$instances = array_merge($instances, field_read_instances(array('field_id' => $field['id']), array('include_inactive' => TRUE)));
}
foreach ($instances as $instance) {
$update_instance = FALSE;
foreach ($instance['display'] as $view_mode => $display) {
if (strpos($display['type'], 'styles_image_') === 0) {
$update_instance = TRUE;
$image_style = substr($display['type'], strlen('styles_image_'));
$instance['display'][$view_mode]['type'] = 'image';
$instance['display'][$view_mode]['settings'] = array('image_style' => $image_style, 'image_link' => FALSE);
}
}
if ($update_instance) {
field_update_instance($instance);
}
}
}
/**
* Delete duplicate entries from the styles table.
*/
function styles_update_7215() {
$names = db_query("SELECT name FROM {styles} GROUP BY name HAVING COUNT(*) > 1")->fetchCol();
foreach ($names as $name) {
$sids = db_select('styles')
->fields('styles', array('sid', 'name'))
->condition('name', $name)
->orderBy('sid', 'DESC')
->execute()
->fetchCol();
array_shift($sids);
foreach ($sids as $sid) {
db_delete('styles')
->condition('sid', $sid)
->execute();
}
}
}

View File

@@ -0,0 +1,736 @@
<?php
/**
* @file
* Bundles similar display formatters together.
*/
// A registry of variable_get defaults.
include_once('includes/styles.variables.inc');
// Include get_called_class() for PHP < 5.3.
if(!function_exists('get_called_class')) {
include_once('includes/php/get_called_class.inc');
}
/**
* Implements hook_field_formatter_info().
*/
function styles_field_formatter_info() {
$info = array();
foreach (styles_default_styles() as $field_type => $styles) {
foreach ($styles['styles'] as $style) {
$style_name = $style['name'];
$info['styles_' . $field_type . '_' . $style_name] = array(
'label' => t('@field style: @style', array('@field' => ucfirst($field_type), '@style' => $style_name)),
'field types' => array($field_type),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
),
'theme' => array('function' => 'theme_styles_field_formatter')
);
}
}
return $info;
}
/**
* Implements hook_field_formatter_view().
*/
function styles_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array('#formatter' => $display['type']);
foreach ($items as $delta => $item) {
// @todo The variable name 'object' is misleading, but retained for
// backwards compatibility until a broader refactoring of the Styles
// module. For now, it's the $item array cast to an object. For File and
// Image fields, this is a fully loaded file object, because
// file_field_load() loads the referenced file and merges its properties
// into $item, but for other field types, it may simply be raw field data.
$element[$delta] = array('#markup' => theme('styles_field_formatter', array('element' => $element, 'object' => (object) $item, 'delta' => $delta, 'entity' => $entity)));
}
return $element;
}
/**
* Implements hook_theme().
*/
function styles_theme($existing, $type, $theme, $path) {
return array(
'styles' => array(
'variables' => array('field_type' => NULL, 'style_name' => NULL, 'object' => NULL, 'instance' => NULL),
'template' => 'styles',
'path' => $path . '/themes',
'file' => 'styles.theme.inc',
),
'styles_field_formatter' => array(
'variables' => array('render element' => 'element', 'element' => NULL, 'object' => NULL),
'path' => $path . '/themes',
'file' => 'styles.theme.inc',
),
);
}
/**
* Return all available containers for a specific field type.
*
* Modules implementing this hook should supply an array for each field type
* that it supports, with at least two keys: 'containers', containing an
* associated array described below, and 'filter callback' => A function to call
* with the field object to determine which container to implement.
*
* Each container under a field type should be an associative array with the
* following keys:
* 'class' => The class to instantiate when filtering to this container.
* 'filter match' => (Optional) A value to pass to the filter callback
* to match the field object against this container.
*
* Example implementation of hook_styles_default_containers():
* array(
* 'emvideo' => array(
* 'filter callback' => 'my_styles_emvideo_filter',
* 'containers' => array(
* 'brightcove' => array(
* 'class' => 'BrightcoveStyles',
* 'filter match' => array('brightcove'),
* ),
* 'vimeo' => array(
* 'class' => 'VimeoStyles',
* 'filter match' => array('vimeo'),
* ),
* 'youtube' => array(
* 'class' => 'YouTubeStyles',
* 'filter match' => array('youtube', 'my_youtube'),
* ),
* ),
* ),
* );
*
* @param string $return_type
* (Optional) The field type, such as file or nodereference.
* @param boolean $reset
* (Optional) If TRUE, then we reset the cache.
*/
function styles_default_containers($return_type = NULL, $reset = FALSE) {
$styles = &drupal_static(__FUNCTION__);
// Grab from cache or build the array.
if (!isset($styles) || $reset) {
if (($cache = cache_get('styles_default_containers', 'cache_styles')) && !$reset) {
$styles = $cache->data;
}
else {
$styles = array();
styles_module_load_all_includes();
foreach (module_implements('styles_default_containers') as $module) {
$module_styles = module_invoke($module, 'styles_default_containers');
foreach ($module_styles as $field_type => $container) {
$styles[$field_type] = isset($styles[$field_type]) ? $styles[$field_type] : array();
// Pull out existing containers before the merge.
$containers = isset($styles[$field_type]['containers']) ? $styles[$field_type]['containers'] : array();
// Merge in the module defined containers.
$styles[$field_type] = array_merge($styles[$field_type], $container);
$styles[$field_type]['containers'] = isset($styles[$field_type]['containers']) ? $styles[$field_type]['containers'] : array();
$styles[$field_type]['containers'] = array_merge($containers, $styles[$field_type]['containers']);
foreach ($container['containers'] as $style_name => $style) {
$style['name'] = $style_name;
$style['module'] = $module;
$style['storage'] = STYLES_STORAGE_DEFAULT;
$styles[$field_type]['containers'][$style_name] = $style;
}
}
}
drupal_alter('styles_default_containers', $styles);
cache_set('styles_default_containers', $styles, 'cache_styles');
}
}
if (isset($return_type)) {
return $styles[$return_type];
}
return $styles;
}
/**
* Return all available styles for a specific field type.
*
* Each style under a field type should be an associative array with the
* following optional keys:
* 'description' => An untranslated human readable description for the style.
* 'default theme' => The theme to call for display if there is no preset
* returned when filtering the field.
* 'default theme arguments' => Any arguments to pass after the first (of
* the field's object itself).
*
* Example implementation of hook_styles_default_styles():
* array(
* 'nodereference' => array(
* 'styles' => array(
* 'thumbnail' => array(
* 'description' => 'Representative thumbnails linking to the content page.',
* 'default theme' => 'my_styles_default_thumbnail',
* ),
* 'small' => array(
* 'description' => 'Small images linking to the content page.',
* 'default theme' => 'my_styles_default_thumbnail',
* ),
* 'teaser' => array(
* 'description' => 'A short summary of the content.',
* 'default theme' => 'node_view',
* 'default theme arguments' => array(TRUE),
* ),
* ),
* ),
* );
*
* This will create those styles, allowing
*
* @param string $field_type
* (Optional) The field type, such as filefield or nodereference.
* @param boolean $reset
* (Optional) If TRUE, then we reset the cache.
*/
function styles_default_styles($return_type = NULL, $reset = FALSE) {
$styles = &drupal_static(__FUNCTION__);
// Grab from cache or build the array.
if (!isset($styles) || $reset) {
if (($cache = cache_get('styles_default_styles', 'cache_styles')) && !$reset) {
$styles = $cache->data;
}
else {
$styles = array();
styles_module_load_all_includes();
foreach (module_implements('styles_default_styles') as $module) {
$module_styles = module_invoke($module, 'styles_default_styles');
foreach ($module_styles as $field_type => $container) {
$styles[$field_type] = isset($styles[$field_type]) ? $styles[$field_type] : array();
$containers = isset($styles[$field_type]['styles']) ? $styles[$field_type]['styles'] : array();
$styles[$field_type] = array_merge($styles[$field_type], $container);
$styles[$field_type]['styles'] = isset($styles[$field_type]['styles']) ? $styles[$field_type]['styles'] : array();
$styles[$field_type]['styles'] = array_merge($containers, $styles[$field_type]['styles']);
foreach ($container['styles'] as $style_name => $style) {
$style['name'] = $style_name;
$style['module'] = $module;
$style['storage'] = STYLES_STORAGE_DEFAULT;
$style['field_type'] = $field_type;
$style['description'] = isset($style['description']) ? $style['description'] : '';
$styles[$field_type]['styles'][$style_name] = $style;
}
}
}
// Add user defined & overridden styles next.
$user_styles = db_select('styles', NULL, array('fetch' => PDO::FETCH_ASSOC))
->fields('styles')
->orderBy('name')
->execute()
->fetchAllAssoc('name', PDO::FETCH_ASSOC);
foreach ($user_styles as $style_name => $style) {
$field_type = $style['field_type'];
$style['module'] = NULL;
$style['storage'] = STYLES_STORAGE_NORMAL;
if (isset($styles[$field_type]['styles'][$style_name]['module'])) {
$style['module'] = $styles[$field_type]['styles'][$style_name]['module'];
$style['storage'] = STYLES_STORAGE_OVERRIDE;
}
$styles[$field_type]['styles'][$style_name] = $style;
}
drupal_alter('styles_default_styles', $styles);
cache_set('styles_default_styles', $styles, 'cache_styles');
}
}
if (isset($return_type)) {
return $styles[$return_type];
}
return $styles;
}
/**
* Return all available presets for field type containers.
*
* Each container under a field type should be an associative array with the
* following keys:
* 'default preset' => The preset to select by default, which may be
* overridden later.
* 'presets' => An associative array keyed by the preset name, each with
* an array of effects to be passed to the implementing class on display.
*
* Example implementation of hook_styles_default_presets():
* array(
* 'filefield' => array(
* 'containers' => array(
* 'imagefield' => array(
* 'default preset' => 'imagecache_thumbnail_linked',
* 'presets' => array(
* 'imagecache_thumbnail_linked' => array(
* 'title' => '[node-title]',
* 'alt' => '[file-description]',
* 'imagecache_preset' => 'thumbnail',
* 'link' => '[node-path]',
* ),
* 'link_to_file' => array(
* 'title' => '[file-title-raw]',
* 'link' => '[file-path]',
* ),
* ),
* ),
* ),
* );
*
* @param string $field_type
* (Optional) The field type, such as filefield or nodereference.
* @param boolean $reset
* (Optional) If TRUE, then we reset the cache.
*/
function styles_default_presets($return_type = NULL, $reset = FALSE) {
$styles = &drupal_static(__FUNCTION__);
// Grab from cache or build the array.
if (!isset($styles) || $reset) {
if (($cache = cache_get('styles_default_presets', 'cache_styles')) && !$reset) {
$styles = $cache->data;
}
else {
$styles = array();
styles_module_load_all_includes();
foreach (module_implements('styles_default_presets') as $module) {
$module_styles = module_invoke($module, 'styles_default_presets');
foreach ($module_styles as $field_type => $container) {
$all_styles = styles_default_styles($field_type);
$styles[$field_type] = isset($styles[$field_type]) ? $styles[$field_type] : array();
$containers = isset($styles[$field_type]['containers']) ? $styles[$field_type]['containers'] : array();
$styles[$field_type] = array_merge($styles[$field_type], $container);
$styles[$field_type]['containers'] = isset($styles[$field_type]['containers']) ? $styles[$field_type]['containers'] : array();
$styles[$field_type]['containers'] = array_merge($containers, $styles[$field_type]['containers']);
foreach ($container['containers'] as $style_name => $style) {
$style['name'] = $style_name;
$style['module'] = $module;
$style['storage'] = STYLES_STORAGE_DEFAULT;
$style['styles'] = isset($style['styles']) ? $style['styles'] : array();
$default_preset = isset($style['default preset']) ? $style['default preset'] : '';
foreach ($all_styles['styles'] as $container_style_name => $container_style) {
if (!isset($style['styles'][$container_style_name])) {
$style['styles'][$container_style_name] = array(
'default preset' => $default_preset,
);
}
}
$styles[$field_type]['containers'][$style_name] = $style;
}
}
}
// Add user-defined and overridden presets.
$query = db_select('styles_preset_instances', 'spi');
$query->join('styles', 's', 's.sid = spi.sid');
$query->join('styles_presets', 'p', 'p.pid = spi.pid');
$query->addField('spi', 'sid');
$query->addField('spi', 'pid');
$query->addField('s', 'name', 'style_name');
$query->addField('p', 'name', 'preset_name');
$query->addField('p', 'field_type', 'field_type');
$query->addField('p', 'container_name', 'container_name');
$user_styles = $query->execute();
foreach ($user_styles as $style) {
if (isset($styles[$style->field_type]) && isset($styles[$style->field_type]['containers'][$style->container_name]) && isset($styles[$style->field_type]['containers'][$style->container_name]['presets'][$style->preset_name]) && isset($styles[$style->field_type]['containers'][$style->container_name]['styles'][$style->style_name])) {
$styles[$style->field_type]['containers'][$style->container_name]['styles'][$style->style_name]['preset'] = $style->preset_name;
}
}
drupal_alter('styles_default_presets', $styles);
cache_set('styles_default_presets', $styles, 'cache_styles');
}
}
if (isset($return_type)) {
return $styles[$return_type];
}
return $styles;
}
/**
* Load all registered module/styles.inc and modules/includes/styles.inc files.
*/
function styles_module_load_all_includes() {
foreach (styles_get_registered_classes() as $class) {
module_load_include('inc', $class['module'], 'styles');
module_load_include('inc', $class['module'], $class['module'] .'/styles');
module_load_include('inc', $class['module'], 'includes/'. $class['module'] .'.styles');
module_load_include('inc', $class['module'], 'includes/styles/'. $class['module'] .'.styles');
}
}
/**
* Builds a registry of Style classes.
*
* Each module supporting a Style will need to implement
* hook_styles_register, which will need to return an associated array keyed by
* the style class name, with an array containing the following key => value
* pairs:
* 'field_types' => An array of field types to apply this style to.
* The following key => value pairs are optional, which will otherwise be
* automatically derived:
* 'name' => The human-readable name of the style.
* 'description' => A description of the style.
* 'path' => The path where the class file resides.
* 'file' => The file containing the class definition.
* 'module' => The module defining the class.
* The following key => value pair will be automatically set to the association
* and cannot be overridden:
* 'class_name' => The actual name of the class.
*
* @param string $style
* (Optional) The style of the specific class registration to return.
* @param boolean $reset
* (Optional) If TRUE, then reset the registration.
* @return array
* If $style is specified, then return only the specified class definition, or
* NULL if there is no such registered class. Otherwise, return the entire
* class definition registry.
*/
function styles_get_registered_classes($return_style = NULL, $reset = FALSE) {
$registered_classes = &drupal_static(__FUNCTION__);
if ($reset || !isset($registered_classes)) {
$registered_classes = array();
// Build our media object class registry.
foreach (module_implements('styles_register') as $module) {
foreach (module_invoke($module, 'styles_register') as $style => $class) {
$registered_classes[$style] = is_array($class) ? $class : array();
$registered_classes[$style]['class_name'] = $style;
if (!isset($registered_classes[$style]['name'])) {
$registered_classes[$style]['name'] = t($style);
}
if (!isset($registered_classes[$style]['description'])) {
$registered_classes[$style]['description'] = t('Class definition for @style.', array('@style' => $style));
}
if (!isset($registered_classes[$style]['path'])) {
$registered_classes[$style]['path'] = drupal_get_path('module', $module);
}
if (!isset($registered_classes[$style]['file'])) {
$registered_classes[$style]['file'] = $style .'.inc';
}
if (!isset($registered_classes[$style]['module'])) {
$registered_classes[$style]['module'] = $module;
}
}
}
}
if (isset($return_style)) {
return $registered_classes[$style];
}
return $registered_classes;
}
/**
* Implementation of hook_init().
*/
function styles_init() {
// Load all registered class definitions.
styles_get_registered_classes();
}
/**
* Return the registered Styles class definition specified by name.
*
* @param string $class_name
* (Optional) The name of the class definition to return. If NULL, then return
* all class definitions.
* @param boolean $reset
* (Optional) If TRUE, then reset the static array of class definitions.
* @return mixed
* Either the specified Styles class definition, or all defined definitions
* if $class_name is NULL.
*/
function styles_get_styles_class_by_class_name($class_name = NULL, $reset = FALSE) {
$classes = &drupal_static(__FUNCTION__);
if (!isset($classes) || $reset) {
$classes = array();
$registered_classes = styles_get_registered_classes();
foreach ($registered_classes as $scheme => $class) {
$classes[$class['class_name']] = $class;
}
}
if (isset($class_name) && isset($classes[$class_name])) {
return $classes[$class_name];
}
else if (!isset($class_name)) {
return $classes;
}
}
function styles_instance($variables) {
static $id = 0;
$variables['id'] = $id++;
$field_type = $variables['field_type'];
$style_name = $variables['style_name'];
$object = $variables['object'];
// Grab the containers for this field type.
$containers = styles_default_containers($field_type);
$variables['containers'] = $containers['containers'];
$callback = $containers['filter callback'];
// Find the correct container for this field type's styles.
if (function_exists($callback)) {
$container = call_user_func_array($callback, array($variables['object'], $variables));
$variables['container'] = $container && isset($variables['containers'][$container]) ? $variables['containers'][$container] : array();
}
else {
$variables['container'] = array();
}
// Grab the styles.
$styles = styles_default_styles($field_type);
$variables['styles'] = $styles['styles'];
$variables['style'] = $style_name && isset($variables['styles'][$style_name]) ? $variables['styles'][$style_name] : array();
// Grab the presets.
$presets = styles_default_presets($field_type);
$variables['presets'] = $container && isset($presets['containers'][$container]) ? $presets['containers'][$container] : array();
$variables['preset_style'] = isset($variables['presets']['styles'][$style_name]) ? $variables['presets']['styles'][$style_name] : array();
$variables['default preset'] = (isset($variables['preset_style']['default preset']) ? $variables['preset_style']['default preset'] : (isset($variables['presets']['default preset']) ? $variables['presets']['default preset'] : ''));
$variables['preset'] = isset($variables['preset_style']['selected preset']) ? $variables['preset_style']['selected preset'] : (isset($variables['preset_style']['preset']) ? $variables['preset_style']['preset'] : $variables['default preset']);
$variables['effects'] = ($variables['preset'] !== '') && isset($variables['presets']['presets'][$variables['preset']]) ? $variables['presets']['presets'][$variables['preset']] : array();
// Instantiate the class and render the output.
if ($class = $variables['container']['class']) {
return new $variables['container']['class']($variables['object'], $variables['effects'], $variables);
}
}
/**
* Load a style by style name or ID. May be used as a loader for menu items.
*
* @param $field_type
* The field type for this style.
* @param $name
* The name of the style.
* @param $sid
* Optional. The numeric id of a style if the name is not known.
* @param $include
* If set, this loader will restrict to a specific type of style, may be
* one of the defined style storage constants.
* @return
* A style array containing the following keys:
* - "sid": The unique style ID.
* - "name": The unique style name.
* If the style name or ID is not valid, an empty array is returned.
*/
function styles_style_load($field_type, $name = NULL, $sid = NULL, $include = NULL) {
$styles = styles_default_styles($field_type);
// If retrieving by name.
if (isset($name) && isset($styles['styles'][$name])) {
$style = $styles['styles'][$name];
}
// If retrieving by style id.
if (!isset($name) && isset($sid)) {
foreach ($styles['styles'] as $name => $database_style) {
if (isset($database_style['sid']) && $database_style['sid'] == $sid) {
$style = $database_style;
break;
}
}
}
// Restrict to the specific type of flag. This bitwise operation basically
// states "if the storage is X, then allow".
if (isset($style) && (!isset($include) || ($style['storage'] & (int) $include))) {
return $style;
}
// Otherwise the style was not found.
return array();
}
/**
* Save a style/preset instance.
*
* @param string $field_type
* The field type of the style/preset to save.
* @param string $container_name
* The container.
* @param string $style_name
* The name of the style to save to.
* @param string $preset_name
* The name of the preset.
* @param boolean $delete_only
* If TRUE, then we delete only, rather than saving.
*
* @return boolean
* Return TRUE, or FALSE if the save was not successful.
*
* @TODO: Throw an error instead?
*/
function styles_style_save_preset($field_type, $container_name, $style_name, $preset_name, $delete_only = FALSE) {
$query = db_select('styles_presets', 'p');
$query->addField('p', 'pid');
$query->condition('p.name', $preset_name);
$query->condition('p.field_type', $field_type);
$query->condition('p.container_name', $container_name);
$result = $query->execute();
foreach ($result as $preset) {
$preset = (array)$preset;
}
if (empty($preset)) {
$preset = array(
'name' => $preset_name,
'field_type' => $field_type,
'container_name' => $container_name
);
drupal_write_record('styles_presets', $preset);
}
$styles = styles_default_styles($field_type);
if (!isset($styles['styles'][$style_name])) {
return FALSE;
}
else {
$style = $styles['styles'][$style_name];
}
if (!isset($style['sid'])) {
return FALSE;
}
// Delete old style/preset instances for this container.
// Unfortunately, we can't use joins with DeleteQuery. See following comment.
db_query("DELETE FROM {styles_preset_instances} WHERE {styles_preset_instances}.sid = :sid AND EXISTS (SELECT * FROM {styles} s, {styles_presets} p WHERE s.sid = {styles_preset_instances}.sid AND p.pid = {styles_preset_instances}.pid AND s.field_type = p.field_type AND p.container_name = :container_name);", array(':sid' => $style['sid'], ':container_name' => $container_name));
// @TODO: See if there's a way to implement something like the following:
// db_delete('styles_preset_instances')
// ->join('styles', 's')
// ->join('styles_presets', 'p')
// ->condition('s.sid', 'styles_preset_instances.sid')
// ->condition('styles_preset_instances.pid', 'p.pid')
// ->condition('s.field_type', 'p.field_type')
// ->condition('styles_preset_instances.sid', $style['sid'])
// ->condition('p.container_name', $container_name)
// ->execute();
// Write the revised style for an update, unless we're only deleting the old.
if (!$delete_only) {
$record = array(
'sid' => $style['sid'],
'pid' => $preset['pid'],
);
drupal_write_record('styles_preset_instances', $record);
}
// Let other modules update as necessary on save.
module_invoke_all('styles_preset_save', $field_type, $container_name, $style_name, $preset_name, $delete_only);
// Clear all caches and flush.
styles_style_flush($style);
return TRUE;
}
function styles_style_delete($field_type, $style_name) {
// Let other modules update as necessary on deletion.
module_invoke_all('styles_delete', $field_type, $style_name);
$sid = db_select('styles', 's')
->fields('s', array('sid'))
->condition('name', $style_name)
->condition('field_type', $field_type)
->execute()
->fetchField();
if ($sid) {
db_delete('styles_preset_instances')
->condition('sid', $sid)
->execute();
db_delete('styles')
->condition('sid', $sid)
->execute();
}
// Clear all caches and flush.
styles_style_flush();
}
function styles_style_save(&$style) {
if (isset($style['sid']) && is_numeric($style['sid'])) {
// Load the existing style to make sure we account for renamed styles.
$old_style = styles_style_load($style['field_type'], NULL, $style['sid']);
styles_style_flush($old_style);
drupal_write_record('styles', $style, 'sid');
if ($old_style['name'] != $style['name']) {
$style['old_name'] = $old_style['name'];
}
}
else if (isset($style['name'])) {
// Load the existing style to make sure we account for renamed styles.
$old_style = styles_style_load($style['field_type'], $style['name']);
styles_style_flush($old_style);
if (isset($old_style['sid'])) {
$style['sid'] = $old_style['sid'];
drupal_write_record('styles', $style, 'sid');
}
else {
drupal_write_record('styles', $style);
$style['is_new'] = TRUE;
}
if (isset($old_style['name'])) {
$style['old_name'] = $old_style['name'];
}
}
else {
drupal_write_record('styles', $style);
$style['is_new'] = TRUE;
}
// Let other modules update as necessary on save.
module_invoke_all('styles_style_save', $style);
// Clear all caches and flush.
styles_style_flush($style);
return $style;
}
/**
* Flush cached defaults for a style.
*
* @param $style
* A style array.
*/
function styles_style_flush($style = NULL) {
// Clear style and preset caches.
cache_clear_all('styles_default_styles', 'cache_styles');
cache_clear_all('styles_default_presets', 'cache_styles');
cache_clear_all('styles_default_containers', 'cache_styles');
drupal_static_reset('styles_default_styles');
drupal_static_reset('styles_default_presets');
drupal_static_reset('styles_default_containers');
drupal_static_reset('styles_get_registered_classes');
// Let other modules update as necessary on flush.
module_invoke_all('styles_style_flush', $style);
// Clear field caches so that formatters may be added for this style.
field_info_cache_clear();
drupal_theme_rebuild();
// Clear page caches when flushing.
if (module_exists('block')) {
cache_clear_all('*', 'cache_block', TRUE);
}
cache_clear_all('*', 'cache_page', TRUE);
}
/**
* Implementation of hook_flush_caches().
*/
function styles_flush_caches() {
return array('cache_styles');
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* @file styles.theme.inc
* Theme and preprocess functions for the Styles project.
*/
function theme_styles_field_formatter($variables) {
$formatter = $variables['element']['#formatter'];
$variables['object'] = (object)$variables['object'];
$output = '';
if (preg_match('@^styles_(.*?)_(.*?)$@i', $formatter, $matches)) {
$variables['field_type'] = $field_type = $matches[1];
$variables['style_name'] = $style_name = $matches[2];
$output = theme('styles', $variables);
}
return $output;
}
function template_preprocess_styles(&$variables) {
// If we have a Styles object instance already, then honor that.
// Otherwise, we'll build a new Styles object instance from our settings.
$variables['instance'] = $variables['instance'] ? $variables['instance'] : styles_instance($variables);
// Add the style name to the wrapper's classes array.
$variables['instance']->arrayPush('classes', $variables['style_name']);
if ($variables['instance']) {
// Prefix and suffix are for the wrapper, such as div or span.
$variables['prefix'] = $variables['instance']->getPrefix();
$variables['suffix'] = $variables['instance']->getSuffix();
// Render the output for the template file.
$variables['output'] = $variables['instance']->display(TRUE);
}
else {
// We have no instance, thus nothing to output.
$variables['output'] = '';
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* @file
* Template file for theme_styles.
*/
/**
* Available variables:
* $field_type => A string with the field type being styled.
* $style_name => A string with the style name.
* $container => The style container with all the style information.
* $style => The style preset being used, with all its information.
* $output => The themed output from the style.
* $id => The unique ID.
*/
?>
<?php print $prefix; ?>
<?php print $output; ?>
<?php print $suffix; ?>