This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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 | * The public-facing functionality of the plugin. |
||
5 | * |
||
6 | * @link http://example.com |
||
7 | * @since 1.0.0 |
||
8 | * |
||
9 | * @package Plugin_Name |
||
10 | * @subpackage Plugin_Name/Frontend |
||
11 | */ |
||
12 | |||
13 | namespace logoscon\WP\RedmineEmbed; |
||
14 | |||
15 | /** |
||
16 | * The public-facing functionality of the plugin. |
||
17 | * |
||
18 | * Defines the plugin name, version, and two examples hooks for how to |
||
19 | * enqueue the dashboard-specific stylesheet and JavaScript. |
||
20 | * |
||
21 | * @package Plugin_Name |
||
22 | * @subpackage Plugin_Name/Frontend |
||
23 | * @author Your Name <[email protected]> |
||
24 | */ |
||
25 | class Frontend { |
||
26 | |||
27 | /** |
||
28 | * The plugin's instance. |
||
29 | * |
||
30 | * @since 1.0.0 |
||
31 | * @access private |
||
32 | * @var Plugin $plugin This plugin's instance. |
||
33 | */ |
||
34 | private $plugin; |
||
35 | |||
36 | /** |
||
37 | * Redmine. |
||
38 | * |
||
39 | * @since 1.0.0 |
||
40 | * @access private |
||
41 | * @var Redmine API client object. |
||
42 | */ |
||
43 | private $api; |
||
44 | |||
45 | /** |
||
46 | * Textile parser. |
||
47 | * |
||
48 | * @since 1.0.0 |
||
49 | * @access private |
||
50 | * @var \Netcarver\Textile |
||
51 | */ |
||
52 | private $textile; |
||
53 | |||
54 | /** |
||
55 | * Initialize the class and set its properties. |
||
56 | * |
||
57 | * @since 1.0.0 |
||
58 | * |
||
59 | * @param Plugin $plugin This plugin's instance. |
||
60 | */ |
||
61 | public function __construct( Plugin $plugin ) { |
||
62 | $this->plugin = $plugin; |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Initialize dependencies. |
||
67 | */ |
||
68 | private function initialize() { |
||
69 | if ( ! isset( $this->api ) ) { |
||
70 | $this->api = new Redmine\Client( $this->plugin ); |
||
0 ignored issues
–
show
|
|||
71 | } |
||
72 | |||
73 | if ( ! isset( $this->url ) ) { |
||
74 | $this->url = new Redmine\UrlBuilder( $this->plugin ); |
||
0 ignored issues
–
show
The property
url does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
75 | } |
||
76 | |||
77 | if ( ! isset( $this->markup ) ) { |
||
78 | $this->markup = new \Netcarver\Textile\Parser(); |
||
0 ignored issues
–
show
The property
markup does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
79 | } |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Register the stylesheets for the public-facing side of the site. |
||
84 | * |
||
85 | * @since 1.0.0 |
||
86 | */ |
||
87 | public function enqueue_styles() { |
||
88 | |||
89 | /** |
||
90 | * This function is provided for demonstration purposes only. |
||
91 | * |
||
92 | * An instance of this class should be passed to the run() function |
||
93 | * defined in Loader as all of the hooks are defined in that particular |
||
94 | * class. |
||
95 | * |
||
96 | * The Loader will then create the relationship between the defined |
||
97 | * hooks and the functions defined in this class. |
||
98 | */ |
||
99 | |||
100 | \wp_enqueue_style( |
||
101 | $this->plugin->get_name(), |
||
102 | \plugin_dir_url( dirname( __FILE__ ) ) . 'styles/frontend.css', |
||
103 | array(), |
||
104 | $this->plugin->get_version(), |
||
105 | 'all' ); |
||
106 | |||
107 | } |
||
108 | |||
109 | /** |
||
110 | * Register URL embed handler. |
||
111 | */ |
||
112 | public function register_embed_handlers () { |
||
113 | $root_url = preg_quote( \trailingslashit( $this->plugin->get_option( 'root_url', false ) ) ); |
||
114 | |||
115 | if ( empty( $root_url ) ) { |
||
116 | return; |
||
117 | } |
||
118 | |||
119 | \wp_embed_register_handler( 'redmine', '#^' . $root_url . 'issues/(?<id>\d+)#i', array( $this, 'embed_issue' ), true ); |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * Outputs Redmine issue details. |
||
124 | * |
||
125 | * @param array $matches [description] |
||
126 | * @param array $attr [description] |
||
127 | * @param string $url [description] |
||
128 | * @param array $rawattr [description] |
||
129 | */ |
||
130 | public function embed_issue( $matches, $attr, $url, $rawattr ) { |
||
131 | $this->initialize(); |
||
132 | |||
133 | $issue_id = (int) $matches['id']; |
||
134 | |||
135 | try { |
||
136 | $data = $this->api->get_issue( $issue_id, array(), false ); |
||
137 | |||
138 | } catch ( \Exception $e ) { |
||
139 | $is_unauthorized = $e->getCode() === 401 || $e->getCode() === 403; |
||
140 | $error = array(); |
||
141 | |||
142 | $error[] = sprintf( |
||
143 | \__( 'Unable to display issue <a href="%s">#%d</a>: %s.', 'redmine-embed' ), |
||
144 | \esc_url( $this->url->get_public_url( 'issues', $issue_id ) ), |
||
145 | $issue_id, |
||
146 | \esc_html( $e->getMessage() ) |
||
147 | ); |
||
148 | |||
149 | if ( \is_user_logged_in() && $is_unauthorized ) { |
||
150 | $error[] = sprintf( |
||
151 | \__( 'Please review <a href="%s" title="%s">your API key settings</a>.', 'redmine-embed' ), |
||
152 | \esc_url( \get_edit_user_link() ), |
||
153 | \esc_attr__( 'Edit your profile', 'redmine-embed' ) |
||
154 | ); |
||
155 | } |
||
156 | |||
157 | return $this->render_error( implode( ' ', $error ) ); |
||
158 | } |
||
159 | |||
160 | return $this->render_issue( $this->prepare_issue( $data ) ); |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Get template file path. |
||
165 | * |
||
166 | * @param string $template Template file (without the extension) to include. |
||
167 | * @return string Absolute path to the requested template file. |
||
168 | */ |
||
169 | private function get_template( $template ) { |
||
170 | return sprintf( '%s/templates/%s.php', dirname( __DIR__ ), $template ); |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Render error message. |
||
175 | * |
||
176 | * @param string $error Error message. |
||
0 ignored issues
–
show
There is no parameter named
$error . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
177 | */ |
||
178 | private function render_issue( $issue ) { |
||
179 | ob_start(); |
||
180 | require $this->get_template( 'issue' ); |
||
181 | return ob_get_clean(); |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Render error message. |
||
186 | * |
||
187 | * @param string $error Error message. |
||
188 | */ |
||
189 | private function render_error( $error ) { |
||
190 | ob_start(); |
||
191 | require $this->get_template( 'error' ); |
||
192 | return ob_get_clean(); |
||
193 | } |
||
194 | |||
195 | /** |
||
196 | * Add rendered fields to the data object. |
||
197 | * @param object $data Issue data. |
||
198 | * @return object Issue data with added fields. |
||
199 | */ |
||
200 | private function prepare_issue( $data ) { |
||
201 | $data->issue->rendered = (object) array( |
||
202 | 'description' => $this->markup->textileRestricted( $data->issue->description ), |
||
203 | 'created_on' => $this->get_formatted_date( strtotime( $data->issue->created_on ) ), |
||
204 | 'updated_on' => $this->get_formatted_date( strtotime( $data->issue->updated_on ) ), |
||
205 | ); |
||
206 | |||
207 | $data->issue->link = $this->url->get_public_url( 'issues', $data->issue->id ); |
||
208 | $data->issue->spent_hours_link = $this->url->get_public_url( 'issues', $data->issue->id, '/time_entries' ); |
||
209 | $data->issue->assigned_to->link = $this->url->get_public_url( 'users', $data->issue->assigned_to->id ); |
||
210 | $data->issue->author->link = $this->url->get_public_url( 'users', $data->issue->author->id ); |
||
211 | $data->issue->fixed_version->link = $this->url->get_public_url( 'versions', $data->issue->fixed_version->id ); |
||
212 | |||
213 | return $data->issue; |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Format date. |
||
218 | * @param int $timestamp Timestamp. |
||
219 | * @return string Formatted date based on the timestamp. |
||
220 | */ |
||
221 | private function get_formatted_date( $timestamp = 0 ) { |
||
222 | $format = sprintf( |
||
223 | _x( '%1$s \a\t %2$s', 'date and time format', 'redmine-embed' ), |
||
224 | \get_option( 'date_format' ), |
||
225 | \get_option( 'time_format' ) |
||
226 | ); |
||
227 | |||
228 | return \date_i18n( $format, $timestamp ); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Get object link. |
||
233 | * |
||
234 | * @param object $attribute Attribute containing name and link properties. |
||
235 | * @return string Link markup. |
||
236 | */ |
||
237 | private function get_attribute_link( $attribute ) { |
||
238 | if ( empty( $attribute->name ) ) { |
||
239 | return ''; |
||
240 | } |
||
241 | |||
242 | if ( empty( $attribute->link ) ) { |
||
243 | return \esc_html( $attribute->name ); |
||
244 | } |
||
245 | |||
246 | return sprintf( |
||
247 | '<a href="%s">%s</a>', |
||
248 | \esc_url( $attribute->link ), |
||
249 | \esc_html( $attribute->name ) |
||
250 | ); |
||
251 | } |
||
252 | |||
253 | } |
||
254 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..