Skip to content

Commit ee7cc91

Browse files
committed
*4904* Add subscriptions report for CSV export
1 parent fc1bacf commit ee7cc91

File tree

6 files changed

+436
-0
lines changed

6 files changed

+436
-0
lines changed

docs/README-CSV

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
======================================
2+
=== Comma-Separated Values (CSV) Files
3+
======================================
4+
5+
Importing into a Spreadsheet
6+
----------------------------
7+
8+
Some applications, including Microsoft Excel, do not correctly handle newlines
9+
that are present within CSV data fields.
10+
11+
For example, an address may include street information, followed by a newline,
12+
followed by the city and province, followed by a newline, followed by a postal
13+
code. The newlines are used to provide formatting for the field. This form of
14+
data is valid and part of the CSV specification (please see [1] and [2]).
15+
16+
Applications that do not correctly handle newlines treat data that follows a
17+
newline as a new row of data. This leads to unexpected behaviour and errors
18+
when importing CSV files.
19+
20+
One workaround for this limitation is to use software that correctly processes
21+
CSV files.
22+
23+
For example, OpenOffice can be used to import a CSV file that contains newlines
24+
in data fields. The resulting spreadsheet can either be used as is or OpenOffice
25+
can be used to save the file in Microsoft Excel format (e.g. .xls). The file
26+
can then be opened for editing in Microsoft Excel.
27+
28+
In a similar way, Google Docs can be used to import the CSV file. Again, the
29+
resulting spreadsheet may be used as is or Google Docs may be used to save the
30+
file in Microsoft Excel format for editing in Microsoft Excel.
31+
32+
33+
OpenOffice
34+
----------
35+
36+
OpenOffice may be obtained free of charge for Windows, Mac, and Linux:
37+
http://www.openoffice.org
38+
39+
Alternately, Mac users can use NeoOffice, an OpenOffice port for the Mac:
40+
http://www.neooffice.org
41+
42+
43+
Google Docs
44+
-----------
45+
46+
Google Docs require an Internet connection and a Google account:
47+
http://docs.google.com
48+
49+
50+
Additional Information
51+
----------------------
52+
53+
[1] http://tools.ietf.org/html/rfc4180
54+
[2] http://en.wikipedia.org/wiki/Comma-separated_values

plugins/reports/subscriptions/README

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
======================================
2+
=== Subscriptions Report Plugin
3+
======================================
4+
5+
To import the generated CSV file into a spreadsheet application, please see
6+
docs/README-CSV in your OJS installation directory.
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
<?php
2+
3+
/**
4+
* @file SubscriptionReportPlugin.inc.php
5+
*
6+
* Copyright (c) 2003-2010 John Willinsky
7+
* Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
8+
*
9+
* @class SubscriptionReportPlugin
10+
* @ingroup plugins_reports_subscription
11+
*
12+
* @brief Subscription report plugin
13+
*/
14+
15+
import('classes.plugins.ReportPlugin');
16+
17+
class SubscriptionReportPlugin extends ReportPlugin {
18+
/**
19+
* Called as a plugin is registered to the registry
20+
* @param $category String Name of category plugin was registered to
21+
* @return boolean True if plugin initialized successfully; if false,
22+
* the plugin will not be registered.
23+
*/
24+
function register($category, $path) {
25+
$success = parent::register($category, $path);
26+
$this->addLocaleData();
27+
return $success;
28+
}
29+
30+
/**
31+
* Get the name of this plugin. The name must be unique within
32+
* its category.
33+
* @return String name of plugin
34+
*/
35+
function getName() {
36+
return 'SubscriptionReportPlugin';
37+
}
38+
39+
/**
40+
* Get the display name of this plugin.
41+
* @return String display name of plugin
42+
*/
43+
function getDisplayName() {
44+
return Locale::translate('plugins.reports.subscriptions.displayName');
45+
}
46+
47+
/**
48+
* Get the description text for this plugin.
49+
* @return String description text for this plugin
50+
*/
51+
function getDescription() {
52+
return Locale::translate('plugins.reports.subscriptions.description');
53+
}
54+
55+
/**
56+
* Generate the subscription report and write CSV contents to file
57+
* @param $args array Request arguments
58+
*/
59+
function display(&$args) {
60+
$journal =& Request::getJournal();
61+
$journalId = $journal->getId();
62+
$userDao =& DAORegistry::getDAO('UserDAO');
63+
$countryDao =& DAORegistry::getDAO('CountryDAO');
64+
$subscriptionTypeDao =& DAORegistry::getDAO('SubscriptionTypeDAO');
65+
$individualSubscriptionDao =& DAORegistry::getDAO('IndividualSubscriptionDAO');
66+
$institutionalSubscriptionDao =& DAORegistry::getDAO('InstitutionalSubscriptionDAO');
67+
68+
header('content-type: text/comma-separated-values');
69+
header('content-disposition: attachment; filename=subscriptions-' . date('Ymd') . '.csv');
70+
$fp = fopen('php://output', 'wt');
71+
72+
// Columns for individual subscriptions
73+
$columns = array(Locale::translate('plugins.reports.subscriptions.individualSubscriptions'));
74+
String::fputcsv($fp, array_values($columns));
75+
76+
$columns = array(
77+
'subscription_id' => Locale::translate('plugins.reports.subscriptions.subscriptionId'),
78+
'status' => Locale::translate('plugins.reports.subscriptions.status'),
79+
'type' => Locale::translate('plugins.reports.subscriptions.type'),
80+
'format' => Locale::translate('plugins.reports.subscriptions.format'),
81+
'date_start' => Locale::translate('plugins.reports.subscriptions.dateStart'),
82+
'date_end' => Locale::translate('plugins.reports.subscriptions.dateEnd'),
83+
'membership' => Locale::translate('plugins.reports.subscriptions.membership'),
84+
'reference_number' => Locale::translate('plugins.reports.subscriptions.referenceNumber'),
85+
'notes' => Locale::translate('plugins.reports.subscriptions.notes'),
86+
'name' => Locale::translate('plugins.reports.subscriptions.name'),
87+
'mailing_address' => Locale::translate('plugins.reports.subscriptions.mailingAddress'),
88+
'country' => Locale::translate('plugins.reports.subscriptions.country'),
89+
'email' => Locale::translate('plugins.reports.subscriptions.email'),
90+
'phone' => Locale::translate('plugins.reports.subscriptions.phone'),
91+
'fax' => Locale::translate('plugins.reports.subscriptions.fax')
92+
);
93+
94+
// Write out individual subscription column headings to file
95+
String::fputcsv($fp, array_values($columns));
96+
97+
// Iterate over individual subscriptions and write out each to file
98+
$individualSubscriptions =& $individualSubscriptionDao->getSubscriptionsByJournalId($journalId);
99+
while ($subscription =& $individualSubscriptions->next()) {
100+
$user =& $userDao->getUser($subscription->getUserId());
101+
$subscriptionType =& $subscriptionTypeDao->getSubscriptionType($subscription->getTypeId());
102+
103+
foreach ($columns as $index => $junk) {
104+
switch ($index) {
105+
case 'subscription_id':
106+
$columns[$index] = $subscription->getId();
107+
break;
108+
case 'status':
109+
$columns[$index] = $subscription->getStatusString();
110+
break;
111+
case 'type':
112+
$columns[$index] = $subscription->getSubscriptionTypeSummaryString();
113+
break;
114+
case 'format':
115+
$columns[$index] = Locale::translate($subscriptionType->getFormatString());
116+
break;
117+
case 'date_start':
118+
$columns[$index] = $subscription->getDateStart();
119+
break;
120+
case 'date_end':
121+
$columns[$index] = $subscription->getDateEnd();
122+
break;
123+
case 'membership':
124+
$columns[$index] = $subscription->getMembership();
125+
break;
126+
case 'reference_number':
127+
$columns[$index] = $subscription->getReferenceNumber();
128+
break;
129+
case 'notes':
130+
$columns[$index] = $this->_html2text($subscription->getNotes());
131+
break;
132+
case 'name':
133+
$columns[$index] = $user->getFullName();
134+
break;
135+
case 'mailing_address':
136+
$columns[$index] = $this->_html2text($user->getMailingAddress());
137+
break;
138+
case 'country':
139+
$columns[$index] = $countryDao->getCountry($user->getCountry());
140+
break;
141+
case 'email':
142+
$columns[$index] = $user->getEmail();
143+
break;
144+
case 'phone':
145+
$columns[$index] = $user->getPhone();
146+
break;
147+
case 'fax':
148+
$columns[$index] = $user->getFax();
149+
break;
150+
default:
151+
$columns[$index] = '';
152+
}
153+
}
154+
155+
String::fputcsv($fp, $columns);
156+
}
157+
158+
// Columns for institutional subscriptions
159+
$columns = array('');
160+
String::fputcsv($fp, array_values($columns));
161+
162+
$columns = array(Locale::translate('plugins.reports.subscriptions.institutionalSubscriptions'));
163+
String::fputcsv($fp, array_values($columns));
164+
165+
$columns = array(
166+
'subscription_id' => Locale::translate('plugins.reports.subscriptions.subscriptionId'),
167+
'status' => Locale::translate('plugins.reports.subscriptions.status'),
168+
'type' => Locale::translate('plugins.reports.subscriptions.type'),
169+
'format' => Locale::translate('plugins.reports.subscriptions.format'),
170+
'date_start' => Locale::translate('plugins.reports.subscriptions.dateStart'),
171+
'date_end' => Locale::translate('plugins.reports.subscriptions.dateEnd'),
172+
'membership' => Locale::translate('plugins.reports.subscriptions.membership'),
173+
'reference_number' => Locale::translate('plugins.reports.subscriptions.referenceNumber'),
174+
'notes' => Locale::translate('plugins.reports.subscriptions.notes'),
175+
'institution_name' => Locale::translate('plugins.reports.subscriptions.institutionName'),
176+
'institution_mailing_address' => Locale::translate('plugins.reports.subscriptions.institutionMailingAddress'),
177+
'domain' => Locale::translate('plugins.reports.subscriptions.domain'),
178+
'ip_ranges' => Locale::translate('plugins.reports.subscriptions.ipRanges'),
179+
'contact' => Locale::translate('plugins.reports.subscriptions.contact'),
180+
'mailing_address' => Locale::translate('plugins.reports.subscriptions.mailingAddress'),
181+
'country' => Locale::translate('plugins.reports.subscriptions.country'),
182+
'email' => Locale::translate('plugins.reports.subscriptions.email'),
183+
'phone' => Locale::translate('plugins.reports.subscriptions.phone'),
184+
'fax' => Locale::translate('plugins.reports.subscriptions.fax')
185+
);
186+
187+
// Write out institutional subscription column headings to file
188+
String::fputcsv($fp, array_values($columns));
189+
190+
// Iterate over institutional subscriptions and write out each to file
191+
$institutionalSubscriptions =& $institutionalSubscriptionDao->getSubscriptionsByJournalId($journalId);
192+
while ($subscription =& $institutionalSubscriptions->next()) {
193+
$user =& $userDao->getUser($subscription->getUserId());
194+
$subscriptionType =& $subscriptionTypeDao->getSubscriptionType($subscription->getTypeId());
195+
196+
foreach ($columns as $index => $junk) {
197+
switch ($index) {
198+
case 'subscription_id':
199+
$columns[$index] = $subscription->getId();
200+
break;
201+
case 'status':
202+
$columns[$index] = $subscription->getStatusString();
203+
break;
204+
case 'type':
205+
$columns[$index] = $subscription->getSubscriptionTypeSummaryString();
206+
break;
207+
case 'format':
208+
$columns[$index] = Locale::translate($subscriptionType->getFormatString());
209+
break;
210+
case 'date_start':
211+
$columns[$index] = $subscription->getDateStart();
212+
break;
213+
case 'date_end':
214+
$columns[$index] = $subscription->getDateEnd();
215+
break;
216+
case 'membership':
217+
$columns[$index] = $subscription->getMembership();
218+
break;
219+
case 'reference_number':
220+
$columns[$index] = $subscription->getReferenceNumber();
221+
break;
222+
case 'notes':
223+
$columns[$index] = $this->_html2text($subscription->getNotes());
224+
break;
225+
case 'institution_name':
226+
$columns[$index] = $subscription->getInstitutionName();
227+
break;
228+
case 'institution_mailing_address':
229+
$columns[$index] = $subscription->getInstitutionMailingAddress();
230+
break;
231+
case 'domain':
232+
$columns[$index] = $subscription->getDomain();
233+
break;
234+
case 'ip_ranges':
235+
$columns[$index] = $this->_formatIPRanges($subscription->getIPRanges());
236+
break;
237+
case 'contact':
238+
$columns[$index] = $user->getFullName();
239+
break;
240+
case 'mailing_address':
241+
$columns[$index] = $this->_html2text($user->getMailingAddress());
242+
break;
243+
case 'country':
244+
$columns[$index] = $countryDao->getCountry($user->getCountry());
245+
break;
246+
case 'email':
247+
$columns[$index] = $user->getEmail();
248+
break;
249+
case 'phone':
250+
$columns[$index] = $user->getPhone();
251+
break;
252+
case 'fax':
253+
$columns[$index] = $user->getFax();
254+
break;
255+
default:
256+
$columns[$index] = '';
257+
}
258+
}
259+
260+
String::fputcsv($fp, $columns);
261+
}
262+
263+
fclose($fp);
264+
}
265+
266+
/**
267+
* Replace HTML "newline" tags (p, li, br) with line feeds. Strip all other tags.
268+
* @param $html String Input HTML string
269+
* @return String Text with replaced and stripped HTML tags
270+
*/
271+
function _html2text($html) {
272+
$html = String::regexp_replace('/<[\/]?p>/', chr(10), $html);
273+
$html = String::regexp_replace('/<li>/', '&bull; ', $html);
274+
$html = String::regexp_replace('/<\/li>/', chr(10), $html);
275+
$html = String::regexp_replace('/<br[ ]?[\/]?>/', chr(10), $html);
276+
$html = String::html2utf(strip_tags($html));
277+
return $html;
278+
}
279+
280+
/**
281+
* Pretty format IP ranges, one per line via line feeds.
282+
* @param $ipRanges array IP ranges
283+
* @return String Text of IP ranges formatted with newlines
284+
*/
285+
function _formatIPRanges($ipRanges) {
286+
$numRanges = count($ipRanges);
287+
$ipRangesString = '';
288+
289+
for($i=0; $i<$numRanges; $i++) {
290+
$ipRangesString .= $ipRanges[$i];
291+
if ( $i+1 < $numRanges) $ipRangesString .= chr(10);
292+
}
293+
294+
return $ipRangesString;
295+
}
296+
}
297+
298+
?>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/**
4+
* @defgroup plugins_reports_subscription
5+
*/
6+
7+
/**
8+
* @file plugins/reports/subscriptions/index.php
9+
*
10+
* Copyright (c) 2003-2010 John Willinsky
11+
* Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
12+
*
13+
* @ingroup plugins_reports_subscription
14+
* @brief Wrapper for subscription report plugin.
15+
*
16+
*/
17+
18+
require_once('SubscriptionReportPlugin.inc.php');
19+
20+
return new SubscriptionReportPlugin();
21+
22+
?>

0 commit comments

Comments
 (0)