function persistentUrl($params)
 {
     if (defined('PERSISTENT_UPLOAD_URLS') && PERSISTENT_UPLOAD_URLS) {
         $url_path = NDownload::cleanUrl($params['file']);
         $parts = NDownload::getAssetAttributes($url_path);
         NDownload::setAssetAttributes($parts);
         $model_name = NDownload::getAssetModelName();
         $url = UPLOAD_DIR . '/' . $model_name . '/' . $params['field'] . '/' . $params['id'];
         return $url;
     } else {
         return $params['file'];
     }
 }
 function export($model_name)
 {
     if (isset($model_name)) {
         $model = NModel::factory($model_name);
         // Foreign Key Lookup Support
         if (isset($model->excel_export)) {
             $model_foreign_keys = $model->excel_export;
             // Default standard foreign keys get added and merged here.
             $foreign_keys = array_merge($this->default_foreign_keys, $model_foreign_keys);
         } else {
             $foreign_keys = $this->default_foreign_keys;
         }
         // Field Inclusion and Exclusion Support
         if (isset($model->excel_exclude_fields)) {
             $model_excel_inclusions = $model->excel_exclude_fields;
             $field_exclusions = array_merge($this->default_field_exclusions, $model_excel_inclusions);
         } else {
             $field_exclusions = $this->default_field_exclusions;
         }
         // If $_GET['search'] is set, only export those items.
         $search = isset($_GET['search']) ? $_GET['search'] : null;
         $search_field = isset($_GET['search_field']) ? $_GET['search_field'] : null;
         if (isset($search) && $search != null) {
             if (!$search_field && $search_field != null) {
                 $acon = NController::factory('asset');
                 $search_field = isset($model->search_field) ? $model->search_field : $acon->search_field;
                 unset($acon);
             }
         }
         $options = $search ? array('conditions' => "{$search_field} LIKE '%{$search}%'") : array();
         // Can set options in the model about items exported to the Excel.
         // Only export items that meet a certain criteria - not everything in the list.
         // For example: $this->viewlist_options = array('conditions'=>"cms_modified_by_user = '******'");
         if (isset($model->viewlist_options)) {
             foreach ($model->viewlist_options as $key => $val) {
                 if (isset($options[$key])) {
                     $options[$key] .= ' AND ' . $val;
                 } else {
                     $options[$key] = "{$val}";
                 }
             }
         }
         if ($model->find($options)) {
             $fields = $model->fields();
             // Add additional custom fields here from the model file.
             if (isset($model->excel_extra_fields)) {
                 foreach ($model->excel_extra_fields as $key => $value) {
                     $fields[] = $key;
                 }
             }
             // Creating a workbook
             $filename = $_SERVER['DOCUMENT_ROOT'] . UPLOAD_DIR . '/' . rand(1, 1000) . '-file.csv';
             $fp = fopen($filename, 'w');
             // Creating a workbook and sending it directly out to a browser.
             //$fp = fopen('php://output', 'w');
             // Let's add the field names to the title line.
             // Leave out a few.
             $x = 0;
             foreach ($fields as $field) {
                 $exclude_this = array_key_exists($field, $field_exclusions);
                 if ($exclude_this && $field_exclusions[$field] == true) {
                     // do nothing
                 } else {
                     $good_fields[] = $field;
                 }
             }
             //$field_string = implode(',', $good_fields);
             fputcsv($fp, $good_fields);
             // Now here comes the data.
             $y = 1;
             while ($model->fetch()) {
                 $data_fields = array();
                 $item = $model->toArray();
                 // For reference while we're working with things.
                 $original_item = array();
                 $original_item = $item;
                 $x = 0;
                 foreach ($fields as $field) {
                     $exclude_this = array_key_exists($field, $field_exclusions);
                     if ($exclude_this && $field_exclusions[$field] == true) {
                         // do nothing
                     } else {
                         // Look for foreign keys and replace if assigned.
                         foreach ($foreign_keys as $foreign_key => $foreign_key_value) {
                             if ($field == $foreign_key) {
                                 $fk_model_name = $foreign_key_value[0];
                                 $fk_model_headline = $foreign_key_value[1];
                                 $fk_model = NModel::factory($fk_model_name);
                                 if ($fk_model && $fk_model->get($item[$field])) {
                                     $item[$field] = $fk_model->{$fk_model_headline};
                                 }
                                 unset($fk_model);
                             }
                         }
                         //Look for bitmask fields and replace with string value instead of numeric total
                         if (is_array($model->bitmask_fields) && count($model->bitmask_fields)) {
                             $bitmask_keys = array_keys($model->bitmask_fields);
                             if (in_array($field, $bitmask_keys)) {
                                 $bitmask_total = $item[$field];
                                 $value_str = '';
                                 $i = 0;
                                 foreach ($model->bitmask_fields[$field] as $bit => $val) {
                                     if ($bit & $bitmask_total) {
                                         if ($i > 0) {
                                             $value_str .= ', ';
                                         }
                                         $value_str .= $val;
                                         $i++;
                                     }
                                 }
                                 $item[$field] = $value_str;
                             }
                         }
                         // Any extra fields get dealt with here.
                         if (isset($model->excel_extra_fields)) {
                             foreach ($model->excel_extra_fields as $key => $value) {
                                 if ($field == $key) {
                                     $extra_name = $value[0];
                                     $extra_attribute = $value[1];
                                     $extra_key = $value[2];
                                     $extra_info = NModel::factory($extra_name);
                                     if (method_exists($extra_info, $extra_attribute)) {
                                         $item[$field] = $extra_info->{$extra_attribute}($original_item["{$extra_key}"]);
                                     } else {
                                         $extra_info->get($original_item["{$extra_key}"]);
                                         $item[$field] = $extra_info->{$extra_attribute};
                                     }
                                     unset($extra_info);
                                 }
                             }
                         }
                         // If it's an uploaded file, put the address in the conf.php before it so that it
                         // turns into a link in Excel.
                         if (eregi(UPLOAD_DIR, $item[$field])) {
                             $item[$field] = PUBLIC_SITE . ereg_replace("^/", "", $item[$field]);
                         }
                         $fixed_item = $this->convert_characters($item[$field]);
                         $data_fields[] = $fixed_item;
                     }
                 }
                 //$data_string = implode(',', $data_fields);
                 fputcsv($fp, $data_fields);
                 unset($original_item);
                 unset($item);
                 unset($data_fields);
             }
             // Close the file.
             fclose($fp);
             $download = new NDownload();
             $download->serveFile($filename);
             unlink($filename);
         }
     }
 }