Passed
Push — master ( ed222d...64e89d )
by
unknown
02:51
created
src/PageTypes/BaseHomePage.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -26,137 +26,137 @@
 block discarded – undo
26 26
  */
27 27
 class BaseHomePage extends Page
28 28
 {
29
-    private static $icon = 'cwp/cwp:images/icons/sitetree_images/home.png';
30
-
31
-    private static $hide_ancestor = BaseHomePage::class;
32
-
33
-    private static $singular_name = 'Home Page';
34
-
35
-    private static $plural_name = 'Home Pages';
36
-
37
-    private static $table_name = 'BaseHomePage';
38
-
39
-    private static $db = [
40
-        'FeatureOneTitle' => 'Varchar(255)',
41
-        'FeatureOneCategory' => "Enum('bell,comments,film,flag,globe,group,list,phone,rss,time,user','comments')",
42
-        'FeatureOneContent' => 'HTMLText',
43
-        'FeatureOneButtonText' => 'Varchar(255)',
44
-        'FeatureTwoTitle' => 'Varchar(255)',
45
-        'FeatureTwoCategory' => "Enum('bell,comments,film,flag,globe,group,list,phone,rss,time,user','comments')",
46
-        'FeatureTwoContent' => 'HTMLText',
47
-        'FeatureTwoButtonText' => 'Varchar(255)'
48
-    ];
49
-
50
-    private static $has_one = [
51
-        'LearnMorePage' => SiteTree::class,
52
-        'FeatureOneLink' => SiteTree::class,
53
-        'FeatureTwoLink' => SiteTree::class,
54
-    ];
55
-
56
-    private static $has_many = [
57
-        'Quicklinks' => Quicklink::class . '.Parent',
58
-    ];
59
-
60
-    public function Quicklinks()
61
-    {
62
-        return $this->getComponents('Quicklinks')->sort('SortOrder');
63
-    }
64
-
65
-    public function getCMSFields()
66
-    {
67
-        $this->beforeUpdateCMSFields(function (FieldList $fields) {
68
-            // Main Content tab
69
-            $fields->addFieldToTab(
70
-                'Root.Main',
71
-                TreeDropdownField::create(
72
-                    'LearnMorePageID',
73
-                    _t(__CLASS__ . '.LearnMoreLink', 'Page to link the "Learn More" button to:'),
74
-                    SiteTree::class
75
-                ),
76
-                'Metadata'
77
-            );
78
-
79
-            $gridField = GridField::create(
80
-                'Quicklinks',
81
-                'Quicklinks',
82
-                $this->Quicklinks(),
83
-                GridFieldConfig_RelationEditor::create()
84
-            );
85
-            $gridConfig = $gridField->getConfig();
86
-            $gridConfig->getComponentByType(GridFieldAddNewButton::class)->setButtonName(
87
-                _t(__CLASS__ . '.AddNewButton', 'Add new')
88
-            );
89
-
90
-            $injector = Injector::inst();
91
-
92
-            $gridConfig->removeComponentsByType(GridFieldAddExistingAutocompleter::class);
93
-            $gridConfig->removeComponentsByType(GridFieldDeleteAction::class);
94
-            $gridConfig->addComponent($injector->create(GridFieldDeleteAction::class));
95
-            $gridConfig->addComponent($injector->create(GridFieldSortableRows::class, 'SortOrder'));
96
-            $gridField->setModelClass(Quicklink::class);
97
-
98
-            $fields->addFieldToTab('Root.Quicklinks', $gridField);
99
-
100
-            $fields->removeByName('Import');
101
-
102
-            $fields->addFieldToTab(
103
-                'Root.Features',
104
-                ToggleCompositeField::create(
105
-                    'FeatureOne',
106
-                    _t(__CLASS__ . '.FeatureOne', 'Feature One'),
107
-                    array(
108
-                        TextField::create('FeatureOneTitle', _t(__CLASS__ . '.Title', 'Title')),
109
-                        $dropdownField = DropdownField::create(
110
-                            'FeatureOneCategory',
111
-                            _t(__CLASS__ . '.FeatureCategoryDropdown', 'Category icon'),
112
-                            singleton(BaseHomePage::class)->dbObject('FeatureOneCategory')->enumValues()
113
-                        ),
114
-                        HTMLEditorField::create(
115
-                            'FeatureOneContent',
116
-                            _t(__CLASS__ . '.FeatureContentFieldLabel', 'Content')
117
-                        ),
118
-                        TextField::create(
119
-                            'FeatureOneButtonText',
120
-                            _t(__CLASS__ . '.FeatureButtonText', 'Button text')
121
-                        ),
122
-                        TreeDropdownField::create(
123
-                            'FeatureOneLinkID',
124
-                            _t(__CLASS__ . '.FeatureLink', 'Page to link to'),
125
-                            SiteTree::class
126
-                        )->setDescription(_t(__CLASS__ . '.ButtonTextRequired', 'Button text must be filled in'))
127
-                    )
128
-                )->setHeadingLevel(3)
129
-            );
130
-            $dropdownField->setEmptyString('none');
131
-
132
-            $fields->addFieldToTab('Root.Features', ToggleCompositeField::create(
133
-                'FeatureTwo',
134
-                _t(__CLASS__ . '.FeatureTwo', 'Feature Two'),
135
-                array(
136
-                    TextField::create('FeatureTwoTitle', _t(__CLASS__ . '.Title', 'Title')),
137
-                    $dropdownField = DropdownField::create(
138
-                        'FeatureTwoCategory',
139
-                        _t(__CLASS__ . '.FeatureCategoryDropdown', 'Category icon'),
140
-                        singleton(BaseHomePage::class)->dbObject('FeatureTwoCategory')->enumValues()
141
-                    ),
142
-                    HTMLEditorField::create(
143
-                        'FeatureTwoContent',
144
-                        _t(__CLASS__ . '.FeatureContentFieldLabel', 'Content')
145
-                    ),
146
-                    TextField::create(
147
-                        'FeatureTwoButtonText',
148
-                        _t(__CLASS__ . '.FeatureButtonText', 'Button text')
149
-                    ),
150
-                    TreeDropdownField::create(
151
-                        'FeatureTwoLinkID',
152
-                        _t(__CLASS__ . '.FeatureLink', 'Page to link to'),
153
-                        SiteTree::class
154
-                    )->setDescription(_t(__CLASS__ . '.ButtonTextRequired', 'Button text must be filled in'))
155
-                )
156
-            )->setHeadingLevel(3));
157
-            $dropdownField->setEmptyString('none');
158
-        });
159
-
160
-        return parent::getCMSFields();
161
-    }
29
+	private static $icon = 'cwp/cwp:images/icons/sitetree_images/home.png';
30
+
31
+	private static $hide_ancestor = BaseHomePage::class;
32
+
33
+	private static $singular_name = 'Home Page';
34
+
35
+	private static $plural_name = 'Home Pages';
36
+
37
+	private static $table_name = 'BaseHomePage';
38
+
39
+	private static $db = [
40
+		'FeatureOneTitle' => 'Varchar(255)',
41
+		'FeatureOneCategory' => "Enum('bell,comments,film,flag,globe,group,list,phone,rss,time,user','comments')",
42
+		'FeatureOneContent' => 'HTMLText',
43
+		'FeatureOneButtonText' => 'Varchar(255)',
44
+		'FeatureTwoTitle' => 'Varchar(255)',
45
+		'FeatureTwoCategory' => "Enum('bell,comments,film,flag,globe,group,list,phone,rss,time,user','comments')",
46
+		'FeatureTwoContent' => 'HTMLText',
47
+		'FeatureTwoButtonText' => 'Varchar(255)'
48
+	];
49
+
50
+	private static $has_one = [
51
+		'LearnMorePage' => SiteTree::class,
52
+		'FeatureOneLink' => SiteTree::class,
53
+		'FeatureTwoLink' => SiteTree::class,
54
+	];
55
+
56
+	private static $has_many = [
57
+		'Quicklinks' => Quicklink::class . '.Parent',
58
+	];
59
+
60
+	public function Quicklinks()
61
+	{
62
+		return $this->getComponents('Quicklinks')->sort('SortOrder');
63
+	}
64
+
65
+	public function getCMSFields()
66
+	{
67
+		$this->beforeUpdateCMSFields(function (FieldList $fields) {
68
+			// Main Content tab
69
+			$fields->addFieldToTab(
70
+				'Root.Main',
71
+				TreeDropdownField::create(
72
+					'LearnMorePageID',
73
+					_t(__CLASS__ . '.LearnMoreLink', 'Page to link the "Learn More" button to:'),
74
+					SiteTree::class
75
+				),
76
+				'Metadata'
77
+			);
78
+
79
+			$gridField = GridField::create(
80
+				'Quicklinks',
81
+				'Quicklinks',
82
+				$this->Quicklinks(),
83
+				GridFieldConfig_RelationEditor::create()
84
+			);
85
+			$gridConfig = $gridField->getConfig();
86
+			$gridConfig->getComponentByType(GridFieldAddNewButton::class)->setButtonName(
87
+				_t(__CLASS__ . '.AddNewButton', 'Add new')
88
+			);
89
+
90
+			$injector = Injector::inst();
91
+
92
+			$gridConfig->removeComponentsByType(GridFieldAddExistingAutocompleter::class);
93
+			$gridConfig->removeComponentsByType(GridFieldDeleteAction::class);
94
+			$gridConfig->addComponent($injector->create(GridFieldDeleteAction::class));
95
+			$gridConfig->addComponent($injector->create(GridFieldSortableRows::class, 'SortOrder'));
96
+			$gridField->setModelClass(Quicklink::class);
97
+
98
+			$fields->addFieldToTab('Root.Quicklinks', $gridField);
99
+
100
+			$fields->removeByName('Import');
101
+
102
+			$fields->addFieldToTab(
103
+				'Root.Features',
104
+				ToggleCompositeField::create(
105
+					'FeatureOne',
106
+					_t(__CLASS__ . '.FeatureOne', 'Feature One'),
107
+					array(
108
+						TextField::create('FeatureOneTitle', _t(__CLASS__ . '.Title', 'Title')),
109
+						$dropdownField = DropdownField::create(
110
+							'FeatureOneCategory',
111
+							_t(__CLASS__ . '.FeatureCategoryDropdown', 'Category icon'),
112
+							singleton(BaseHomePage::class)->dbObject('FeatureOneCategory')->enumValues()
113
+						),
114
+						HTMLEditorField::create(
115
+							'FeatureOneContent',
116
+							_t(__CLASS__ . '.FeatureContentFieldLabel', 'Content')
117
+						),
118
+						TextField::create(
119
+							'FeatureOneButtonText',
120
+							_t(__CLASS__ . '.FeatureButtonText', 'Button text')
121
+						),
122
+						TreeDropdownField::create(
123
+							'FeatureOneLinkID',
124
+							_t(__CLASS__ . '.FeatureLink', 'Page to link to'),
125
+							SiteTree::class
126
+						)->setDescription(_t(__CLASS__ . '.ButtonTextRequired', 'Button text must be filled in'))
127
+					)
128
+				)->setHeadingLevel(3)
129
+			);
130
+			$dropdownField->setEmptyString('none');
131
+
132
+			$fields->addFieldToTab('Root.Features', ToggleCompositeField::create(
133
+				'FeatureTwo',
134
+				_t(__CLASS__ . '.FeatureTwo', 'Feature Two'),
135
+				array(
136
+					TextField::create('FeatureTwoTitle', _t(__CLASS__ . '.Title', 'Title')),
137
+					$dropdownField = DropdownField::create(
138
+						'FeatureTwoCategory',
139
+						_t(__CLASS__ . '.FeatureCategoryDropdown', 'Category icon'),
140
+						singleton(BaseHomePage::class)->dbObject('FeatureTwoCategory')->enumValues()
141
+					),
142
+					HTMLEditorField::create(
143
+						'FeatureTwoContent',
144
+						_t(__CLASS__ . '.FeatureContentFieldLabel', 'Content')
145
+					),
146
+					TextField::create(
147
+						'FeatureTwoButtonText',
148
+						_t(__CLASS__ . '.FeatureButtonText', 'Button text')
149
+					),
150
+					TreeDropdownField::create(
151
+						'FeatureTwoLinkID',
152
+						_t(__CLASS__ . '.FeatureLink', 'Page to link to'),
153
+						SiteTree::class
154
+					)->setDescription(_t(__CLASS__ . '.ButtonTextRequired', 'Button text must be filled in'))
155
+				)
156
+			)->setHeadingLevel(3));
157
+			$dropdownField->setEmptyString('none');
158
+		});
159
+
160
+		return parent::getCMSFields();
161
+	}
162 162
 }
Please login to merge, or discard this patch.
src/PageTypes/BasePageController.php 1 patch
Indentation   +283 added lines, -283 removed lines patch added patch discarded remove patch
@@ -21,293 +21,293 @@
 block discarded – undo
21 21
 
22 22
 class BasePageController extends ContentController
23 23
 {
24
-    private static $allowed_actions = [
25
-        'downloadpdf',
26
-        'SearchForm',
27
-        'results',
28
-    ];
29
-
30
-    /**
31
-     * How many search results should be shown per-page?
32
-     *
33
-     * @config
34
-     * @var int
35
-     */
36
-    private static $results_per_page = 10;
37
-
38
-    /**
39
-     * If spelling suggestions for searches are given, enable
40
-     * suggested searches to be followed immediately
41
-     *
42
-     * @config
43
-     * @var bool
44
-     */
45
-    private static $search_follow_suggestions = true;
46
-
47
-    /**
48
-     * Which classes should be queried when searching?
49
-     *
50
-     * @config
51
-     * @var array
52
-     */
53
-    private static $classes_to_search = [
54
-        [
55
-            'class' => 'Page',
56
-            'includeSubclasses' => true,
57
-        ]
58
-    ];
59
-
60
-    /**
61
-     * Serve the page rendered as PDF.
62
-     */
63
-    public function downloadpdf()
64
-    {
65
-        if (!Config::inst()->get(BasePage::class, 'pdf_export')) {
66
-            return false;
67
-        }
68
-
69
-        // We only allow producing live pdf. There is no way to secure the draft files.
70
-        Versioned::set_stage(Versioned::LIVE);
71
-
72
-        $path = $this->dataRecord->getPdfFilename();
73
-        if (!file_exists($path)) {
74
-            $this->generatePDF();
75
-        }
76
-
77
-        return HTTPRequest::send_file(file_get_contents($path), basename($path), 'application/pdf');
78
-    }
79
-
80
-    /*
24
+	private static $allowed_actions = [
25
+		'downloadpdf',
26
+		'SearchForm',
27
+		'results',
28
+	];
29
+
30
+	/**
31
+	 * How many search results should be shown per-page?
32
+	 *
33
+	 * @config
34
+	 * @var int
35
+	 */
36
+	private static $results_per_page = 10;
37
+
38
+	/**
39
+	 * If spelling suggestions for searches are given, enable
40
+	 * suggested searches to be followed immediately
41
+	 *
42
+	 * @config
43
+	 * @var bool
44
+	 */
45
+	private static $search_follow_suggestions = true;
46
+
47
+	/**
48
+	 * Which classes should be queried when searching?
49
+	 *
50
+	 * @config
51
+	 * @var array
52
+	 */
53
+	private static $classes_to_search = [
54
+		[
55
+			'class' => 'Page',
56
+			'includeSubclasses' => true,
57
+		]
58
+	];
59
+
60
+	/**
61
+	 * Serve the page rendered as PDF.
62
+	 */
63
+	public function downloadpdf()
64
+	{
65
+		if (!Config::inst()->get(BasePage::class, 'pdf_export')) {
66
+			return false;
67
+		}
68
+
69
+		// We only allow producing live pdf. There is no way to secure the draft files.
70
+		Versioned::set_stage(Versioned::LIVE);
71
+
72
+		$path = $this->dataRecord->getPdfFilename();
73
+		if (!file_exists($path)) {
74
+			$this->generatePDF();
75
+		}
76
+
77
+		return HTTPRequest::send_file(file_get_contents($path), basename($path), 'application/pdf');
78
+	}
79
+
80
+	/*
81 81
     * This will return either pdf_base_url from YML, CWP_SECURE_DOMAIN
82 82
     * from _ss_environment, or blank. In that order of importance.
83 83
     */
84
-    public function getPDFBaseURL()
85
-    {
86
-        //if base url YML is defined in YML, use that
87
-        if (Config::inst()->get(BasePage::class, 'pdf_base_url')) {
88
-            $pdfBaseUrl = Config::inst()->get(BasePage::class, 'pdf_base_url').'/';
89
-            //otherwise, if we are CWP use the secure domain
90
-        } elseif (Environment::getEnv('CWP_SECURE_DOMAIN')) {
91
-            $pdfBaseUrl = Environment::getEnv('CWP_SECURE_DOMAIN') . '/';
92
-            //or if neither, leave blank
93
-        } else {
94
-            $pdfBaseUrl = '';
95
-        }
96
-        return $pdfBaseUrl;
97
-    }
98
-
99
-    /*
84
+	public function getPDFBaseURL()
85
+	{
86
+		//if base url YML is defined in YML, use that
87
+		if (Config::inst()->get(BasePage::class, 'pdf_base_url')) {
88
+			$pdfBaseUrl = Config::inst()->get(BasePage::class, 'pdf_base_url').'/';
89
+			//otherwise, if we are CWP use the secure domain
90
+		} elseif (Environment::getEnv('CWP_SECURE_DOMAIN')) {
91
+			$pdfBaseUrl = Environment::getEnv('CWP_SECURE_DOMAIN') . '/';
92
+			//or if neither, leave blank
93
+		} else {
94
+			$pdfBaseUrl = '';
95
+		}
96
+		return $pdfBaseUrl;
97
+	}
98
+
99
+	/*
100 100
     * Don't use the proxy if the pdf domain is the CWP secure domain
101 101
     * Or if we aren't on a CWP server
102 102
     */
103
-    public function getPDFProxy($pdfBaseUrl)
104
-    {
105
-        if (!Environment::getEnv('CWP_SECURE_DOMAIN')
106
-            || $pdfBaseUrl == Environment::getEnv('CWP_SECURE_DOMAIN') . '/'
107
-        ) {
108
-            $proxy = '';
109
-        } else {
110
-            $proxy = ' --proxy ' . Environment::getEnv('SS_OUTBOUND_PROXY')
111
-                . ':' . Environment::getEnv('SS_OUTBOUND_PROXY_PORT');
112
-        }
113
-        return $proxy;
114
-    }
115
-
116
-    /**
117
-     * Render the page as PDF using wkhtmltopdf.
118
-     */
119
-    public function generatePDF()
120
-    {
121
-        if (!Config::inst()->get(BasePage::class, 'pdf_export')) {
122
-            return false;
123
-        }
124
-
125
-        $binaryPath = Config::inst()->get(BasePage::class, 'wkhtmltopdf_binary');
126
-        if (!$binaryPath || !is_executable($binaryPath)) {
127
-            if (Environment::getEnv('WKHTMLTOPDF_BINARY')
128
-                && is_executable(Environment::getEnv('WKHTMLTOPDF_BINARY'))
129
-            ) {
130
-                $binaryPath = Environment::getEnv('WKHTMLTOPDF_BINARY');
131
-            }
132
-        }
133
-
134
-        if (!$binaryPath) {
135
-            user_error('Neither WKHTMLTOPDF_BINARY nor BasePage.wkhtmltopdf_binary are defined', E_USER_ERROR);
136
-        }
137
-
138
-        if (Versioned::get_reading_mode() == 'Stage.Stage') {
139
-            user_error('Generating PDFs on draft is not supported', E_USER_ERROR);
140
-        }
141
-
142
-        set_time_limit(60);
143
-
144
-        // prepare the paths
145
-        $pdfFile = $this->dataRecord->getPdfFilename();
146
-        $bodyFile = str_replace('.pdf', '_pdf.html', $pdfFile);
147
-        $footerFile = str_replace('.pdf', '_pdffooter.html', $pdfFile);
148
-
149
-        // make sure the work directory exists
150
-        if (!file_exists(dirname($pdfFile))) {
151
-            Filesystem::makeFolder(dirname($pdfFile));
152
-        }
153
-
154
-        //decide the domain to use in generation
155
-        $pdfBaseUrl = $this->getPDFBaseURL();
156
-
157
-        // Force http protocol on CWP - fetching from localhost without using the proxy, SSL terminates on gateway.
158
-        if (Environment::getEnv('CWP_ENVIRONMENT')) {
159
-            Config::modify()->set(Director::class, 'alternate_protocol', 'http');
160
-            //only set alternate protocol if CWP_SECURE_DOMAIN is defined OR pdf_base_url is
161
-            if ($pdfBaseUrl) {
162
-                Config::modify()->set(Director::class, 'alternate_base_url', 'http://' . $pdfBaseUrl);
163
-            }
164
-        }
165
-
166
-        $bodyViewer = $this->getViewer('pdf');
167
-
168
-        // write the output of this page to HTML, ready for conversion to PDF
169
-        file_put_contents($bodyFile, $bodyViewer->process($this));
170
-
171
-        // get the viewer for the current template with _pdffooter
172
-        $footerViewer = $this->getViewer('pdffooter');
173
-
174
-        // write the output of the footer template to HTML, ready for conversion to PDF
175
-        file_put_contents($footerFile, $footerViewer->process($this));
176
-
177
-        //decide what the proxy should look like
178
-        $proxy = $this->getPDFProxy($pdfBaseUrl);
179
-
180
-        // finally, generate the PDF
181
-        $command = $binaryPath . $proxy . ' --outline -B 40pt -L 20pt -R 20pt -T 20pt --encoding utf-8 '
182
-            . '--orientation Portrait --disable-javascript --quiet --print-media-type ';
183
-        $retVal = 0;
184
-        $output = array();
185
-        exec(
186
-            $command . " --footer-html \"$footerFile\" \"$bodyFile\" \"$pdfFile\" &> /dev/stdout",
187
-            $output,
188
-            $retVal
189
-        );
190
-
191
-        // remove temporary file
192
-        unlink($bodyFile);
193
-        unlink($footerFile);
194
-
195
-        // output any errors
196
-        if ($retVal != 0) {
197
-            user_error('wkhtmltopdf failed: ' . implode("\n", $output), E_USER_ERROR);
198
-        }
199
-
200
-        // serve the generated file
201
-        return HTTPRequest::send_file(file_get_contents($pdfFile), basename($pdfFile), 'application/pdf');
202
-    }
203
-
204
-    /**
205
-     * Site search form
206
-     */
207
-    public function SearchForm()
208
-    {
209
-        $searchText = $this->getRequest()->getVar('Search');
210
-
211
-        $fields = FieldList::create(
212
-            TextField::create('Search', false, $searchText)
213
-        );
214
-        $actions = FieldList::create(
215
-            FormAction::create('results', _t('SilverStripe\\CMS\\Search\\SearchForm.GO', 'Go'))
216
-        );
217
-
218
-        $form = SearchForm::create($this, SearchForm::class, $fields, $actions);
219
-        $form->setFormAction('search/SearchForm');
220
-
221
-        return $form;
222
-    }
223
-
224
-    /**
225
-     * Get search form with _header suffix
226
-     *
227
-     * @return SearchForm
228
-     */
229
-    public function HeaderSearchForm()
230
-    {
231
-        return $this->SearchForm()->setTemplate('SearchForm_header');
232
-    }
233
-
234
-    /**
235
-     * Process and render search results.
236
-     *
237
-     * @param array $data The raw request data submitted by user
238
-     * @param SearchForm $form The form instance that was submitted
239
-     * @param HTTPRequest $request Request generated for this action
240
-     * @return DBHTMLText
241
-     */
242
-    public function results($data, $form, $request)
243
-    {
244
-        // Check parameters for terms, pagination, and if we should follow suggestions
245
-        $keywords = empty($data['Search']) ? '' : $data['Search'];
246
-        $start = isset($data['start']) ? $data['start'] : 0;
247
-        $suggestions = isset($data['suggestions'])
248
-            ? $data['suggestions']
249
-            : $this->config()->get('search_follow_suggestions');
250
-
251
-        $results = CwpSearchEngine::create()
252
-            ->search(
253
-                $keywords,
254
-                $this->config()->get('classes_to_search'),
255
-                Injector::inst()->get(CwpSearchEngine::class . '.search_index'),
256
-                $this->config()->get('results_per_page'),
257
-                $start,
258
-                $suggestions
259
-            );
260
-
261
-        // Customise content with these results
262
-        $properties = [
263
-            'MetaTitle' => _t(__CLASS__ . '.MetaTitle', 'Search {keywords}', ['keywords' => $keywords]),
264
-            'NoSearchResults' => _t(__CLASS__ . '.NoResult', 'Sorry, your search query did not return any results.'),
265
-            'EmptySearch' => _t(__CLASS__ . '.EmptySearch', 'Search field empty, please enter your search query.'),
266
-            'PdfLink' => '',
267
-            'Title' => _t('SilverStripe\\CMS\\Search\\SearchForm.SearchResults', 'Search Results'),
268
-        ];
269
-        $this->extend('updateSearchResults', $results, $properties);
270
-
271
-        // Customise page
272
-        $response = $this->customise($properties);
273
-        if ($results) {
274
-            $response = $response
275
-                ->customise($results)
276
-                ->customise(array( 'Results' => $results->getResults() ));
277
-        }
278
-
279
-        // Render
280
-        $templates = $this->getResultsTemplate($request);
281
-        return $response->renderWith($templates);
282
-    }
283
-
284
-    /**
285
-     * Select the template to render search results with
286
-     *
287
-     * @param HTTPRequest $request
288
-     * @return array
289
-     */
290
-    protected function getResultsTemplate($request)
291
-    {
292
-        $templates = [Page::class . '_results', Page::class];
293
-        if ($request->getVar('format') == 'rss') {
294
-            array_unshift($templates, 'Page_results_rss');
295
-        }
296
-        if ($request->getVar('format') == 'atom') {
297
-            array_unshift($templates, 'Page_results_atom');
298
-        }
299
-        return $templates;
300
-    }
301
-
302
-    /**
303
-     * Provide current year.
304
-     */
305
-    public function CurrentDatetime()
306
-    {
307
-        return DBDatetime::now();
308
-    }
309
-
310
-    public function getRSSLink()
311
-    {
312
-    }
103
+	public function getPDFProxy($pdfBaseUrl)
104
+	{
105
+		if (!Environment::getEnv('CWP_SECURE_DOMAIN')
106
+			|| $pdfBaseUrl == Environment::getEnv('CWP_SECURE_DOMAIN') . '/'
107
+		) {
108
+			$proxy = '';
109
+		} else {
110
+			$proxy = ' --proxy ' . Environment::getEnv('SS_OUTBOUND_PROXY')
111
+				. ':' . Environment::getEnv('SS_OUTBOUND_PROXY_PORT');
112
+		}
113
+		return $proxy;
114
+	}
115
+
116
+	/**
117
+	 * Render the page as PDF using wkhtmltopdf.
118
+	 */
119
+	public function generatePDF()
120
+	{
121
+		if (!Config::inst()->get(BasePage::class, 'pdf_export')) {
122
+			return false;
123
+		}
124
+
125
+		$binaryPath = Config::inst()->get(BasePage::class, 'wkhtmltopdf_binary');
126
+		if (!$binaryPath || !is_executable($binaryPath)) {
127
+			if (Environment::getEnv('WKHTMLTOPDF_BINARY')
128
+				&& is_executable(Environment::getEnv('WKHTMLTOPDF_BINARY'))
129
+			) {
130
+				$binaryPath = Environment::getEnv('WKHTMLTOPDF_BINARY');
131
+			}
132
+		}
133
+
134
+		if (!$binaryPath) {
135
+			user_error('Neither WKHTMLTOPDF_BINARY nor BasePage.wkhtmltopdf_binary are defined', E_USER_ERROR);
136
+		}
137
+
138
+		if (Versioned::get_reading_mode() == 'Stage.Stage') {
139
+			user_error('Generating PDFs on draft is not supported', E_USER_ERROR);
140
+		}
141
+
142
+		set_time_limit(60);
143
+
144
+		// prepare the paths
145
+		$pdfFile = $this->dataRecord->getPdfFilename();
146
+		$bodyFile = str_replace('.pdf', '_pdf.html', $pdfFile);
147
+		$footerFile = str_replace('.pdf', '_pdffooter.html', $pdfFile);
148
+
149
+		// make sure the work directory exists
150
+		if (!file_exists(dirname($pdfFile))) {
151
+			Filesystem::makeFolder(dirname($pdfFile));
152
+		}
153
+
154
+		//decide the domain to use in generation
155
+		$pdfBaseUrl = $this->getPDFBaseURL();
156
+
157
+		// Force http protocol on CWP - fetching from localhost without using the proxy, SSL terminates on gateway.
158
+		if (Environment::getEnv('CWP_ENVIRONMENT')) {
159
+			Config::modify()->set(Director::class, 'alternate_protocol', 'http');
160
+			//only set alternate protocol if CWP_SECURE_DOMAIN is defined OR pdf_base_url is
161
+			if ($pdfBaseUrl) {
162
+				Config::modify()->set(Director::class, 'alternate_base_url', 'http://' . $pdfBaseUrl);
163
+			}
164
+		}
165
+
166
+		$bodyViewer = $this->getViewer('pdf');
167
+
168
+		// write the output of this page to HTML, ready for conversion to PDF
169
+		file_put_contents($bodyFile, $bodyViewer->process($this));
170
+
171
+		// get the viewer for the current template with _pdffooter
172
+		$footerViewer = $this->getViewer('pdffooter');
173
+
174
+		// write the output of the footer template to HTML, ready for conversion to PDF
175
+		file_put_contents($footerFile, $footerViewer->process($this));
176
+
177
+		//decide what the proxy should look like
178
+		$proxy = $this->getPDFProxy($pdfBaseUrl);
179
+
180
+		// finally, generate the PDF
181
+		$command = $binaryPath . $proxy . ' --outline -B 40pt -L 20pt -R 20pt -T 20pt --encoding utf-8 '
182
+			. '--orientation Portrait --disable-javascript --quiet --print-media-type ';
183
+		$retVal = 0;
184
+		$output = array();
185
+		exec(
186
+			$command . " --footer-html \"$footerFile\" \"$bodyFile\" \"$pdfFile\" &> /dev/stdout",
187
+			$output,
188
+			$retVal
189
+		);
190
+
191
+		// remove temporary file
192
+		unlink($bodyFile);
193
+		unlink($footerFile);
194
+
195
+		// output any errors
196
+		if ($retVal != 0) {
197
+			user_error('wkhtmltopdf failed: ' . implode("\n", $output), E_USER_ERROR);
198
+		}
199
+
200
+		// serve the generated file
201
+		return HTTPRequest::send_file(file_get_contents($pdfFile), basename($pdfFile), 'application/pdf');
202
+	}
203
+
204
+	/**
205
+	 * Site search form
206
+	 */
207
+	public function SearchForm()
208
+	{
209
+		$searchText = $this->getRequest()->getVar('Search');
210
+
211
+		$fields = FieldList::create(
212
+			TextField::create('Search', false, $searchText)
213
+		);
214
+		$actions = FieldList::create(
215
+			FormAction::create('results', _t('SilverStripe\\CMS\\Search\\SearchForm.GO', 'Go'))
216
+		);
217
+
218
+		$form = SearchForm::create($this, SearchForm::class, $fields, $actions);
219
+		$form->setFormAction('search/SearchForm');
220
+
221
+		return $form;
222
+	}
223
+
224
+	/**
225
+	 * Get search form with _header suffix
226
+	 *
227
+	 * @return SearchForm
228
+	 */
229
+	public function HeaderSearchForm()
230
+	{
231
+		return $this->SearchForm()->setTemplate('SearchForm_header');
232
+	}
233
+
234
+	/**
235
+	 * Process and render search results.
236
+	 *
237
+	 * @param array $data The raw request data submitted by user
238
+	 * @param SearchForm $form The form instance that was submitted
239
+	 * @param HTTPRequest $request Request generated for this action
240
+	 * @return DBHTMLText
241
+	 */
242
+	public function results($data, $form, $request)
243
+	{
244
+		// Check parameters for terms, pagination, and if we should follow suggestions
245
+		$keywords = empty($data['Search']) ? '' : $data['Search'];
246
+		$start = isset($data['start']) ? $data['start'] : 0;
247
+		$suggestions = isset($data['suggestions'])
248
+			? $data['suggestions']
249
+			: $this->config()->get('search_follow_suggestions');
250
+
251
+		$results = CwpSearchEngine::create()
252
+			->search(
253
+				$keywords,
254
+				$this->config()->get('classes_to_search'),
255
+				Injector::inst()->get(CwpSearchEngine::class . '.search_index'),
256
+				$this->config()->get('results_per_page'),
257
+				$start,
258
+				$suggestions
259
+			);
260
+
261
+		// Customise content with these results
262
+		$properties = [
263
+			'MetaTitle' => _t(__CLASS__ . '.MetaTitle', 'Search {keywords}', ['keywords' => $keywords]),
264
+			'NoSearchResults' => _t(__CLASS__ . '.NoResult', 'Sorry, your search query did not return any results.'),
265
+			'EmptySearch' => _t(__CLASS__ . '.EmptySearch', 'Search field empty, please enter your search query.'),
266
+			'PdfLink' => '',
267
+			'Title' => _t('SilverStripe\\CMS\\Search\\SearchForm.SearchResults', 'Search Results'),
268
+		];
269
+		$this->extend('updateSearchResults', $results, $properties);
270
+
271
+		// Customise page
272
+		$response = $this->customise($properties);
273
+		if ($results) {
274
+			$response = $response
275
+				->customise($results)
276
+				->customise(array( 'Results' => $results->getResults() ));
277
+		}
278
+
279
+		// Render
280
+		$templates = $this->getResultsTemplate($request);
281
+		return $response->renderWith($templates);
282
+	}
283
+
284
+	/**
285
+	 * Select the template to render search results with
286
+	 *
287
+	 * @param HTTPRequest $request
288
+	 * @return array
289
+	 */
290
+	protected function getResultsTemplate($request)
291
+	{
292
+		$templates = [Page::class . '_results', Page::class];
293
+		if ($request->getVar('format') == 'rss') {
294
+			array_unshift($templates, 'Page_results_rss');
295
+		}
296
+		if ($request->getVar('format') == 'atom') {
297
+			array_unshift($templates, 'Page_results_atom');
298
+		}
299
+		return $templates;
300
+	}
301
+
302
+	/**
303
+	 * Provide current year.
304
+	 */
305
+	public function CurrentDatetime()
306
+	{
307
+		return DBDatetime::now();
308
+	}
309
+
310
+	public function getRSSLink()
311
+	{
312
+	}
313 313
 }
Please login to merge, or discard this patch.
src/Search/CwpSearchEngine.php 1 patch
Indentation   +137 added lines, -137 removed lines patch added patch discarded remove patch
@@ -17,141 +17,141 @@
 block discarded – undo
17 17
  */
18 18
 class CwpSearchEngine
19 19
 {
20
-    use Configurable;
21
-    use Extensible;
22
-    use Injectable;
23
-
24
-    /**
25
-     * Default search options
26
-     *
27
-     * @var array
28
-     * @config
29
-     */
30
-    private static $search_options = [
31
-        'hl' => 'true',
32
-    ];
33
-
34
-    /**
35
-     * Additional search options to send to search when spellcheck
36
-     * is included
37
-     *
38
-     * @var array
39
-     * @config
40
-     */
41
-    private static $spellcheck_options = [
42
-        'spellcheck' => 'true',
43
-        'spellcheck.collate' => 'true',
44
-        // spellcheck.dictionary can also be configured to use '_spellcheck'
45
-        // dictionary when indexing fields under the _spellcheckText column
46
-        'spellcheck.dictionary' => 'default',
47
-    ];
48
-
49
-    /**
50
-     * Build a SearchQuery for a new search
51
-     *
52
-     * @param string $keywords
53
-     * @param array $classes
54
-     * @return SearchQuery
55
-     */
56
-    protected function getSearchQuery($keywords, $classes)
57
-    {
58
-        $query = new SearchQuery();
59
-        $query->classes = $classes;
60
-        $query->search($keywords);
61
-        $query->exclude(SiteTree::class . '_ShowInSearch', 0);
62
-
63
-        // Artificially lower the amount of results to prevent too high resource usage.
64
-        // on subsequent canView check loop.
65
-        $query->limit(100);
66
-
67
-        // Allow user code to modify the search query before returning it
68
-        $this->extend('updateSearchQuery', $query);
69
-
70
-        return $query;
71
-    }
72
-
73
-    /**
74
-     * Get solr search options for this query
75
-     *
76
-     * @param bool $spellcheck True if we should include spellcheck support
77
-     * @return array
78
-     */
79
-    protected function getSearchOptions($spellcheck)
80
-    {
81
-        $options = $this->config()->get('search_options');
82
-        if ($spellcheck) {
83
-            $options = array_merge($options, $this->config()->get('spellcheck_options'));
84
-        }
85
-        return $options;
86
-    }
87
-
88
-    /**
89
-     * Get results for a search term
90
-     *
91
-     * @param string $keywords
92
-     * @param array $classes
93
-     * @param SolrIndex $searchIndex
94
-     * @param int $limit Max number of results for this page
95
-     * @param int $start Skip this number of records
96
-     * @param bool $spellcheck True to enable spellcheck
97
-     * @return CwpSearchResult
98
-     */
99
-    protected function getResult($keywords, $classes, $searchIndex, $limit = -1, $start = 0, $spellcheck = false)
100
-    {
101
-        // Prepare options
102
-        $query = $this->getSearchQuery($keywords, $classes);
103
-        $options = $this->getSearchOptions($spellcheck);
104
-
105
-        // Get results
106
-        $solrResult = $searchIndex->search(
107
-            $query,
108
-            $start,
109
-            $limit,
110
-            $options
111
-        );
112
-
113
-        return CwpSearchResult::create($keywords, $solrResult);
114
-    }
115
-
116
-    /**
117
-     * Get a CwpSearchResult for a given criterea
118
-     *
119
-     * @param string $keywords
120
-     * @param array $classes
121
-     * @param SolrIndex $searchIndex
122
-     * @param int $limit Max number of results for this page
123
-     * @param int $start Skip this number of records
124
-     * @param bool $followSuggestions True to enable suggested searches to be returned immediately
125
-     * @return CwpSearchResult|null
126
-     */
127
-    public function search($keywords, $classes, $searchIndex, $limit = -1, $start = 0, $followSuggestions = false)
128
-    {
129
-        if (empty($keywords)) {
130
-            return null;
131
-        }
132
-
133
-        try {
134
-            // Begin search
135
-            $result = $this->getResult($keywords, $classes, $searchIndex, $limit, $start, true);
136
-
137
-            // Return results if we don't need to refine this any further
138
-            if (!$followSuggestions || $result->hasResults() || !$result->getSuggestion()) {
139
-                return $result;
140
-            }
141
-
142
-            // Perform new search with the suggested terms
143
-            $suggested = $result->getSuggestion();
144
-            $newResult = $this->getResult($suggested, $classes, $searchIndex, $limit, $start, false);
145
-            $newResult->setOriginal($keywords);
146
-
147
-            // Compare new results to the original query
148
-            if ($newResult->hasResults()) {
149
-                return $newResult;
150
-            }
151
-
152
-            return $result;
153
-        } catch (Exception $e) {
154
-            Injector::inst()->get(LoggerInterface::class)->warning($e);
155
-        }
156
-    }
20
+	use Configurable;
21
+	use Extensible;
22
+	use Injectable;
23
+
24
+	/**
25
+	 * Default search options
26
+	 *
27
+	 * @var array
28
+	 * @config
29
+	 */
30
+	private static $search_options = [
31
+		'hl' => 'true',
32
+	];
33
+
34
+	/**
35
+	 * Additional search options to send to search when spellcheck
36
+	 * is included
37
+	 *
38
+	 * @var array
39
+	 * @config
40
+	 */
41
+	private static $spellcheck_options = [
42
+		'spellcheck' => 'true',
43
+		'spellcheck.collate' => 'true',
44
+		// spellcheck.dictionary can also be configured to use '_spellcheck'
45
+		// dictionary when indexing fields under the _spellcheckText column
46
+		'spellcheck.dictionary' => 'default',
47
+	];
48
+
49
+	/**
50
+	 * Build a SearchQuery for a new search
51
+	 *
52
+	 * @param string $keywords
53
+	 * @param array $classes
54
+	 * @return SearchQuery
55
+	 */
56
+	protected function getSearchQuery($keywords, $classes)
57
+	{
58
+		$query = new SearchQuery();
59
+		$query->classes = $classes;
60
+		$query->search($keywords);
61
+		$query->exclude(SiteTree::class . '_ShowInSearch', 0);
62
+
63
+		// Artificially lower the amount of results to prevent too high resource usage.
64
+		// on subsequent canView check loop.
65
+		$query->limit(100);
66
+
67
+		// Allow user code to modify the search query before returning it
68
+		$this->extend('updateSearchQuery', $query);
69
+
70
+		return $query;
71
+	}
72
+
73
+	/**
74
+	 * Get solr search options for this query
75
+	 *
76
+	 * @param bool $spellcheck True if we should include spellcheck support
77
+	 * @return array
78
+	 */
79
+	protected function getSearchOptions($spellcheck)
80
+	{
81
+		$options = $this->config()->get('search_options');
82
+		if ($spellcheck) {
83
+			$options = array_merge($options, $this->config()->get('spellcheck_options'));
84
+		}
85
+		return $options;
86
+	}
87
+
88
+	/**
89
+	 * Get results for a search term
90
+	 *
91
+	 * @param string $keywords
92
+	 * @param array $classes
93
+	 * @param SolrIndex $searchIndex
94
+	 * @param int $limit Max number of results for this page
95
+	 * @param int $start Skip this number of records
96
+	 * @param bool $spellcheck True to enable spellcheck
97
+	 * @return CwpSearchResult
98
+	 */
99
+	protected function getResult($keywords, $classes, $searchIndex, $limit = -1, $start = 0, $spellcheck = false)
100
+	{
101
+		// Prepare options
102
+		$query = $this->getSearchQuery($keywords, $classes);
103
+		$options = $this->getSearchOptions($spellcheck);
104
+
105
+		// Get results
106
+		$solrResult = $searchIndex->search(
107
+			$query,
108
+			$start,
109
+			$limit,
110
+			$options
111
+		);
112
+
113
+		return CwpSearchResult::create($keywords, $solrResult);
114
+	}
115
+
116
+	/**
117
+	 * Get a CwpSearchResult for a given criterea
118
+	 *
119
+	 * @param string $keywords
120
+	 * @param array $classes
121
+	 * @param SolrIndex $searchIndex
122
+	 * @param int $limit Max number of results for this page
123
+	 * @param int $start Skip this number of records
124
+	 * @param bool $followSuggestions True to enable suggested searches to be returned immediately
125
+	 * @return CwpSearchResult|null
126
+	 */
127
+	public function search($keywords, $classes, $searchIndex, $limit = -1, $start = 0, $followSuggestions = false)
128
+	{
129
+		if (empty($keywords)) {
130
+			return null;
131
+		}
132
+
133
+		try {
134
+			// Begin search
135
+			$result = $this->getResult($keywords, $classes, $searchIndex, $limit, $start, true);
136
+
137
+			// Return results if we don't need to refine this any further
138
+			if (!$followSuggestions || $result->hasResults() || !$result->getSuggestion()) {
139
+				return $result;
140
+			}
141
+
142
+			// Perform new search with the suggested terms
143
+			$suggested = $result->getSuggestion();
144
+			$newResult = $this->getResult($suggested, $classes, $searchIndex, $limit, $start, false);
145
+			$newResult->setOriginal($keywords);
146
+
147
+			// Compare new results to the original query
148
+			if ($newResult->hasResults()) {
149
+				return $newResult;
150
+			}
151
+
152
+			return $result;
153
+		} catch (Exception $e) {
154
+			Injector::inst()->get(LoggerInterface::class)->warning($e);
155
+		}
156
+	}
157 157
 }
Please login to merge, or discard this patch.