uid == $node->uid))));
}
/**
* Access used within Ubercart Marketplace
*/
function mp_file_uc_mp_feature_access() {
global $user;
return ((user_access('administer product features') || (user_access('administer own product features') && ($user->uid == $node->uid))));
}
/**
* An element process callback for the mp_file_widget.
*
* Includes the option to commit files to product features.
*/
function mp_file_widget_process($element, $edit, &$form_state, $form) {
$element['data']['commit'] = array(
'#type' => variable_get('mp_file_show_commit_checkbox', TRUE) ? 'checkbox' : 'hidden',
'#title' => t('Commit file to product feature'),
'#default_value' => FALSE,
'#value' => variable_get('mp_file_allow_sellers_perm', FALSE),
'#access' => mp_file_uc_mp_feature_access(),
);
return $element;
}
/**
* An element validate callback for the mp_file_widget.
*/
function mp_file_widget_validate($element, &$form_state) { ; }
/**
* Implements hook_nodeapi().
*/
function mp_file_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if (mp_file_product_class_is_enabled($node->type)) {//in_array(, variable_get('mp_product_tools_enabled_classes', array()))) {
if ($op === 'insert' || $op === 'update') {
if ($node->mp_file_attached) {
$file_committed = mp_file_commit($node, $node->mp_file_path, $node->mp_file_description, $node->mp_file_title, $node->mp_file_fid);
if ($file_committed == TRUE) {
mp_file_clear_filefield($node->mp_file_fid, $node->mp_file_path);
drupal_set_message(t('The file was attached to this product. For security reasons, it has now been hidden from the product edit form.'));
}
}
}
elseif ($op === 'load') {
$node->feature_count = 0;
$node->feature_file_name = array();
$result = db_query("SELECT * FROM {uc_product_features} WHERE nid = %d AND fid = 'file' ORDER BY pfid ASC", $node->nid);
while ($feature = db_fetch_object($result)) {
preg_match_all("|[^>]+>(.*)<[^>]+>|U", $feature->description, $out, PREG_PATTERN_ORDER);
$node->feature_file_name[$feature->pfid] = $out[1][1];
$node->feature_count = $node->feature_count + 1;
}
}
elseif ($op === 'prepare') {
if (empty($node->feature_file_name)) {
$node->feature_file_name = array();
}
}
}
}
/**
* Checks to see if this product class has mp_file features enabled
*/
function mp_file_product_class_is_enabled($product_class) {
if ($product_class) {
if (module_exists('mp_product_tools')) {
// Is this even a marketplace product?
if (in_array($product_class, variable_get('mp_product_tools_enabled_classes', array()))) {
$enabled_mp_file_classes = array();
$classes = db_query("SELECT pcid FROM {mp_file_class_settings} WHERE enabled = 1");
while ($class = db_fetch_object($classes)) {
$enabled_mp_file_classes[] = $class->pcid;
}
return in_array($product_class, $enabled_mp_file_classes);
}
else {
FALSE; // This is a standard Ubercart product (non-marketplace)
}
}
else {
TRUE; // If we aren't managing classes, assume we want this product to be digital (otherwise why even enable mp_file?)
}
}
else {
return FALSE;
}
}
/**
* Implements hook_form_alter().
*/
function mp_file_form_alter(&$form, $form_state, $form_id) {
// Strip the class name from the form name, if this is a product class form
$position = strpos($form_id, "_node_form");
$product_class = $position ? substr($form_id, 0, $position) : NULL;
switch ($form_id) {
case mp_file_product_class_is_enabled($product_class):
// Append data to the field download data
$field_name = 'field_'. variable_get('mp_file_field_name', 'download');
// Sift through the elements to add custom process and validation functions to every upload field (should probably just do the first occurance...)
foreach (element_children($form[$field_name]) as $key) {
if ($form[$field_name][$key]['#type'] == 'filefield_widget') {
// Include original process and validation functions and append custom mp_file_widget_process and mp_file_widget_validate
$form[$field_name][$key]['#process'] = array('filefield_widget_process', 'imagefield_widget_widget_process', 'mp_file_widget_process');
$form[$field_name][$key]['#element_validate'] = array('filefield_widget_validate', 'imagefield_widget_validate', 'mp_file_widget_validate');
}
}
// Maybe this should be themed?
$form[t($field_name)]['mp_file_title'] = array(
'#type' => (0 < $form['#node']->feature_count) && variable_get('mp_file_show_feature_list', TRUE) ? 'markup' : 'hidden',
'#prefix' => '
',
'#value' => variable_get('mp_file_replace_feature_on_upload', FALSE)
? 'These features will be replaced when a new product is uploaded:' : 'Delete existing product(s)?',
'#suffix' => '
',
'#weight' => t($form[t($field_name)]['#weight'] + 1),
);
// Product features...
if (!empty($form['#node']->feature_file_name)) {
foreach ($form['#node']->feature_file_name as $pfid => $filename) {
$form[t($field_name)]['mp_file_pfid_' . t($pfid)] = array(
'#type' => variable_get('mp_file_show_feature_list', TRUE) ? 'checkbox' : 'hidden',
'#title' => t($filename),
'#default_value' => variable_get('mp_file_replace_feature_on_upload', FALSE),
'#disabled' => variable_get('mp_file_replace_feature_on_upload', FALSE),
'#weight' => t($form[t($field_name)]['#weight'] + 2),
);
}
}
$form['feature_count'] = array(
'#type' => 'hidden',
'#value' => $form['#node']->feature_count,
);
// Add our own additional form validation and submission functions
$form['#validate'][] = 'mp_file_form_validate';
$form['#submit'][] = 'mp_file_form_submit';
break;
case 'mp_marketplace_settings_seller_form':
$form['mp_file_fieldset']['mp_file_replace_feature_on_upload'] = array(
'#type' => 'checkbox',
'#title' => t('Replace feature on upload'),
'#description' => t('The existing feature(s) will be overwritten automatically by the newest feature uploaded.'),
'#default_value' => variable_get('mp_file_replace_feature_on_upload', FALSE),
);
$form['mp_file_fieldset']['mp_file_require_upload'] = array(
'#type' => 'checkbox',
'#title' => t('Require feature'),
'#description' => t('Requires at least one file feature be attached to the product.'),
'#default_value' => variable_get('mp_file_require_upload', FALSE),
);
// Could probably do this through theming...
$form['mp_file_fieldset']['mp_file_show_commit_checkbox'] = array(
'#type' => 'checkbox',
'#title' => t('Show commit feature checkbox'),
'#description' => t('Shows the commit feature checkbox. Useful if you always plan to, or not to, commit files'),
'#default_value' => variable_get('mp_file_show_commit_checkbox', TRUE),
);
// Could probably do this through theming...
$form['mp_file_fieldset']['mp_file_show_feature_list'] = array(
'#type' => 'checkbox',
'#title' => t('Show feature list on node form'),
'#description' => t('Shows a feature list on the node form. Useful for viewing feature information directly on the node form'),
'#default_value' => variable_get('mp_file_show_feature_list', TRUE),
);
break;
}
return $form;
}
function mp_file_form_validate($form, &$form_state) {
$field_name = 'field_'. variable_get('mp_file_field_name', 'download');
$feature_count = $form_state['values']['feature_count'];
$upload_filename = $form_state['values'][t($field_name)]['0']['filename'];
if (variable_get('mp_file_require_upload', FALSE) && empty($feature_count) && empty($upload_filename)) {
form_set_error(t($field_name), t('No file upload attached.'));
}
}
function mp_file_form_submit($form, &$form_state) {
if (mp_file_uc_mp_feature_access() || variable_get('mp_file_allow_sellers_perm', FALSE) ) {
// Get ready to commit a file if necessary
$field_name = 'field_'. variable_get('mp_file_field_name', 'download');
$field = $form_state['values'][$field_name];
// Collect file features/downloads that are to be deleted, FIX ME, the code below is overkill...
$delete_all_files = TRUE;
$pfid_array = array();
foreach ($field as $key => $value) {
if (drupal_substr($key, 0, drupal_strlen('mp_file_pfid_')) == 'mp_file_pfid_') {
$pfid = drupal_substr($key, drupal_strlen('mp_file_pfid_'));
$pfid_array[$pfid] = variable_get('mp_file_replace_feature_on_upload', FALSE) ? TRUE : $value;
// Is there a $pfid we aren't deleting?
if ($pfid_array[$pfid] == FALSE) {
$delete_all_files = FALSE;
}
}
}
if (empty($pfid_array)) {
$delete_all_files = FALSE;
}
$feature_uploaded = !empty($field[0]['filepath']);
$commit_feature = $field[0]['data']['commit'];
$file_committed = FALSE;
if ($feature_uploaded) {
$description = check_plain($field[0]['description']);
$file_path = $field[0]['filepath'];
$fid = $field[0]['fid'];
$title = $nodearray['title'];
if ($commit_feature && variable_get('mp_file_allow_sellers_perm', FALSE)) {
// nid is not available for new nodes so we have to call mp_file commit
// from nodeapi (an oversite on my part which is leading to less than simple code)
$form_state['values']['mp_file_attached'] = TRUE;
$form_state['values']['mp_file_path'] = $file_path;
$form_state['values']['mp_file_description'] = $description;
$form_state['values']['mp_file_title'] = $title;
$form_state['values']['mp_file_fid'] = $fid;
$file_committed = TRUE;
}
else {
mp_file_clear_filefield($fid, $file_path);
}
}
if ($file_committed || !$delete_all_files) {
mp_file_delete_features($pfid_array);
}
elseif ($delete_all_files == TRUE && !variable_get('mp_file_replace_feature_on_upload', FALSE)) {
drupal_set_message(t("Cannot delete all existing products unless a new product is uploaded."), 'error');
}
}
}
/**
* Clears file from filefield and deletes file from files directory.
* Necessary as a security feature.
*
* NOTE: Bypasses call to hook_filefield('file_delete')
*/
function mp_file_clear_filefield($fid, $file_path) {
db_query('DELETE FROM {files} WHERE fid = %d', $fid);
return file_delete($file_path);
}
/**
* Transfers file download from files directory to file download directory.
* Programatically fills out "product feature form" to commit file.
*
* TODO: add support for model field
*/
function mp_file_commit($node, $file_path, $description, $title, $fid) {
// Check if paths are correctly set
$dir = variable_get('uc_file_base_dir', NULL) .'/';
if (!is_dir($dir)) {
drupal_set_message('File download directory not set.', 'error');
return FALSE;
}
// Rename file...
$file_name = drupal_substr(filename($file_path), 0, strrpos(filename($file_path), "."));
$file_name_ext = drupal_substr(filename($file_path), strrpos(filename($file_path), ".") + 1);
$new_name_hook = module_invoke_all('mp_file_name', $dir, $file_name, $file_name_ext, $node->nid, $title);
$new_name = $new_name_hook[count($new_name_hook)-1];
// Finally, copy the file to a more secure directory
copy($file_path, $dir . $new_name);
//Insert the file to the uc_files table so it will pass validation
$result = db_query("INSERT INTO {uc_files} (filename) VALUES ('%s')", $new_name);
// programatically fill out product feature form
$form_state = Array();
$form_state['values']['uc_file_filename'] = $new_name;
$form_state['values']['uc_file_description'] = $description;
$submitted = drupal_execute('uc_file_feature_form', $form_state, $node, array());
return TRUE;
}
/**
* Implements hook_mp_file_name().
*
* Returns the filename to be used for this feature.
*/
function mp_file_mp_file_name($dir, $file_name, $file_name_ext, $node_id, $title ,$new_name_hook ) {
$node_sanitized_title = preg_replace('/[^0-9a-z\.\_\-]/i', '', $title);
$new_file_name = $node_id . "_" . $file_name . "." . $file_name_ext;
// We could now return $new_file_name but first let's rename it if this file name already exists.
// NB: $file_name also has a counter in it for files in the temp directory
$i_file = 0;
while (file_exists($dir . $new_file_name)) {
$i_file++;
$new_file_name = $node_id . "_" . $file_name . "_" . sprintf('%03d', $i_file) . "." . $file_name_ext;
}
return $new_file_name;
}
/**
* Deletes features listed in the $pfid_array as true
*/
function mp_file_delete_features($pfid_array) {
$fid = 'file';
foreach ($pfid_array as $pfid => $delete_feature) {
if ($delete_feature) {
mp_file_remove_feature($pfid, $fid);
}
}
}
/**
* Deletes a given feature programmatically
*/
function mp_file_remove_feature($pfid, $fid) {
$result = db_query("SELECT * FROM {uc_product_features} WHERE pfid = %d AND fid = '%s'", intval($pfid), $fid);
if ($feature = db_fetch_array($result)) {
// Call the delete function for this product feature if it exists.
$func = uc_product_feature_data($feature['fid'], 'delete');
if (function_exists($func)) {
// $func($feature) should be equivalent to either of the following
// (1) uc_file_feature_delete($feature);
// (2) db_query("DELETE FROM {uc_file_products} WHERE pfid = %d", $feature['pfid']);
$func($feature);
}
// Remove the product feature data from the database.
db_query("DELETE FROM {uc_product_features} WHERE pfid = %d", intval($pfid));
drupal_set_message(t('Product feature ' . t($pfid) . ' has been deleted.'));
}
else {
drupal_set_message(t("Product feature could not be deleted because it doesn't exist."), 'error');
}
}