Issues (12)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

code/CarouselPage.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Provide additional methods specially crafted for carousels.
5
 *
6
 * @package silverstripe-carousel
7
 */
8
class CarouselImageExtension extends DataExtension
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
9
{
10
    /**
11
     * Generate a scaled image suitable for a carousel.
12
     *
13
     * If $width and $height are greater than 0, it is equivalent to
14
     * Image_Backend::croppedResize().
15
     *
16
     * If only $width is greater than 0, it is equivalent to SetWidth().
17
     *
18
     * If only $height is greater than 0, it is equivalent to
19
     * SetHeight().
20
     *
21
     * If neither $width or $height are greater than 0, return the
22
     * original image.
23
     *
24
     * @param  integer $width   The width to set or 0.
25
     * @param  integer $height  The height to set or 0.
26
     * @return Image_Backend
27
     */
28
    public function MaybeCroppedImage($width, $height)
29
    {
30
        return $this->owner->getFormattedImage('MaybeCroppedImage', $width, $height);
31
    }
32
33
    /**
34
     * Low level function for CarouselImageExtension::MaybeCroppedImage().
35
     *
36
     * @param  Image_Backend $backend
37
     * @param  integer $width
38
     * @param  integer $height
39
     * @return Image_Backend
40
     */
41
    public function generateMaybeCroppedImage(Image_Backend $backend, $width, $height)
42
    {
43
        if ($width > 0 && $height > 0) {
44
            return $backend->croppedResize($width, $height);
45
        } elseif ($width > 0) {
46
            return $backend->resizeByWidth($width);
47
        } elseif ($height > 0) {
48
            return $backend->resizeByHeight($height);
49
        } else {
50
            return $backend;
51
        }
52
    }
53
54
    /**
55
     * Retrieve the fields used by SortableUploadField internal form.
56
     *
57
     * @return FieldList
58
     */
59
    public function getCarouselEditFields()
60
    {
61
        // This is *required* otherwise TinyMCE in SilverStripe 3.3 will
62
        // not be enabled and the <textarea> will simply disappear
63
        // without apparent reasons
64
        if (method_exists('HtmlEditorConfig', 'require_js')) {
65
            HtmlEditorConfig::require_js();
66
        }
67
68
        $fields = FieldList::create();
69
        $fields->push(CarouselCaptionField::create('Content', _t('CarouselPage.Caption')));
70
        return $fields;
71
    }
72
}
73
74
/**
75
 * This class is needed in order to handle the 'Content' field of the
76
 * 'File' table with the WYSIWYG editor. That field is TEXT, hence just
77
 * using HtmlEditorField will result in an error when the 'saveInto'
78
 * method is called.
79
 *
80
 * @package silverstripe-carousel
81
 */
82
class CarouselCaptionField extends HtmlEditorField
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
83
{
84
    /**
85
     * Override the default constructor to have saner settings.
86
     *
87
     * @param string      $name  The internal field name, passed to forms.
88
     * @param string|null $title The human-readable field label.
89
     * @param mixed       $value The value of the field.
90
     */
91
    public function __construct($name, $title = null, $value = '')
92
    {
93
        parent::__construct($name, $title, $value);
94
        $this->rows = 5;
95
        // The .htmleditor class enables TinyMCE
96
        $this->addExtraClass('htmleditor');
97
    }
98
99
    /**
100
     * Implementation directly borrowed from HtmlEditorField
101
     * without the blocking or useless code.
102
     *
103
     * @param DataObjectInterface $record
104
     */
105
    public function saveInto(DataObjectInterface $record)
106
    {
107
        $htmlValue = Injector::inst()->create('HTMLValue', $this->value);
108
109
        // Sanitise if requested
110
        if ($this->config()->sanitise_server_side) {
111
            $santiser = Injector::inst()->create('HtmlEditorSanitiser', HtmlEditorConfig::get_active());
112
            $santiser->sanitise($htmlValue);
113
        }
114
115
        $this->extend('processHTML', $htmlValue);
116
        $record->{$this->name} = $htmlValue->getContent();
117
    }
118
}
119
120
/**
121
 * Basic page type owning a carousel.
122
 *
123
 * @package silverstripe-carousel
124
 */
125
class CarouselPage extends Page
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
126
{
127
    private static $icon = 'carousel/img/carousel.png';
128
129
    private static $db = array(
130
        'Captions' => 'Boolean',
131
        'Width'    => 'Int',
132
        'Height'   => 'Int',
133
    );
134
135
    private static $many_many = array(
136
        'Images'   => 'Image',
137
    );
138
139
    private static $many_many_extraFields = array(
140
        'Images'   => array(
141
            'SortOrder' => 'Int',
142
        ),
143
    );
144
145
146
    /**
147
     * Search the first class name (that must have a 'Page' suffix) in
148
     * the object hierarchy that has a correspoding folder in
149
     * ASSETS_PATH, that is a folder with the same name with the 'Page'
150
     * suffix stripped out. This folder will be returned and used as
151
     * custom folder in the upload field.
152
     *
153
     * For example, if this class is `HomePage` and it is inherited from
154
     * `CarouselPage`, this function will check for `Home` first and
155
     * `Carousel` after.
156
     *
157
     * If no valid folders are found, `false` is returned.
158
     *
159
     * @return string|false
160
     */
161
    protected function getClassFolder()
162
    {
163
        for ($class = $this->class; $class; $class = get_parent_class($class)) {
164
            $folder = preg_replace('/Page$/', '', $class);
165
            if ($folder != $class && is_dir(ASSETS_PATH . '/' . $folder)) {
166
                return $folder;
167
            }
168
        }
169
170
        // Why false? Because false is the proper value to set in
171
        // setFolderName() to get the default folder (i.e. 'Uploads').
172
        return false;
173
    }
174
175
    /**
176
     * Add the "Images" tab to the content form of the page.
177
     *
178
     * The images are linked to the page with a many-many relationship,
179
     * so if an image is shared among different carousels there is no
180
     * need to upload it multiple times.
181
     *
182
     * @return FieldList
183
     */
184
    public function getCMSFields()
185
    {
186
        $fields = parent::getCMSFields();
187
188
        $field = SortableUploadField::create('Images', _t('CarouselPage.db_Images'));
189
        $field->setFolderName($this->getClassFolder());
190
        $field->setFileEditFields('getCarouselEditFields');
191
192
        $root = $fields->fieldByName('Root');
193
        $tab = $root->fieldByName('Images');
194
        if (! $tab) {
195
            $tab = Tab::create('Images');
196
            $tab->setTitle(_t('CarouselPage.db_Images'));
197
            $root->insertAfter($tab, 'Main');
198
        }
199
        $tab->push($field);
200
201
        return $fields;
202
    }
203
204
    /**
205
     * Add carousel related fields to the page settings.
206
     *
207
     * Every CarouselPage instance can have its own settings, that is
208
     * different pages can own carousels of different sizes.
209
     *
210
     * @return FieldList
211
     */
212
    public function getSettingsFields()
213
    {
214
        $fields = parent::getSettingsFields();
215
216
        $settings = FieldGroup::create(
217
            FieldGroup::create(
218
                NumericField::create('Width', _t('CarouselPage.db_Width')),
219
                NumericField::create('Height', _t('CarouselPage.db_Height')),
220
                CheckboxField::create('Captions', _t('CarouselPage.db_Captions'))
221
            )
222
        );
223
        $settings->setName('Carousel');
224
        $settings->setTitle(_t('CarouselPage.SINGULARNAME'));
225
        $fields->addFieldToTab('Root.Settings', $settings);
226
227
        return $fields;
228
    }
229
230
    /**
231
     * Ensure ThumbnailWidth and ThumbnailHeight are valorized.
232
     *
233
     * Although width and height for the images in the carousel can be
234
     * omitted (see CarouselImageExtension::MaybeCroppedImage() for
235
     * algorithm details) the thumbnail extents must be defined.
236
     *
237
     * @return Validator
238
     */
239
    public function getCMSValidator()
240
    {
241
        return RequiredFields::create(
242
            'ThumbnailWidth',
243
            'ThumbnailHeight'
244
        );
245
    }
246
247
    /**
248
     * Out of the box support for silverstripe/silverstripe-translatable.
249
     *
250
     * Duplicate the image list whenever a new translation is created.
251
     * It the translatable module is not used, this will simply be a
252
     * dead method.
253
     *
254
     * @param boolean $save Whether the new page should be saved to the
255
     *                      database.
256
     */
257
    public function onTranslatableCreate($save)
258
    {
259
        // Chain up the parent method, if it exists
260
        if (method_exists('Page', 'onTranslatableCreate')) {
261
            parent::onTranslatableCreate($save);
262
        }
263
264
        $master = $this->getTranslation(Translatable::default_locale());
265
266
        foreach ($master->Images() as $master_image) {
267
            $image = $master_image->duplicate($save);
268
            $this->Images()->add($image);
269
        }
270
    }
271
}
272
273
/**
274
 * Controller for CarouselPage.
275
 *
276
 * @package silverstripe-carousel
277
 */
278
class CarouselPage_Controller extends Page_Controller
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
279
{
280
    /**
281
     * From the controller the images are returned in proper order.
282
     * This means `<% loop $Images %>` returns the expected result.
283
     */
284
    public function Images()
285
    {
286
        return $this->dataRecord->Images()->Sort('SortOrder');
287
    }
288
}
289