Skip to content

Commit 5deffd4

Browse files
authored
Introduce phpcs and WP coding standard (#10)
* enable travis phpcs * phpcs fixes
1 parent 16f808c commit 5deffd4

17 files changed

+656
-409
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ matrix:
2929
env: WP_VERSION=latest
3030
# - php: 5.6
3131
# env: WP_VERSION=trunk
32-
# - php: 5.6
33-
# env: WP_TRAVISCI=phpcs
32+
- php: 5.6
33+
env: WP_TRAVISCI=phpcs
3434
# - php: 5.3
3535
# env: WP_VERSION=latest
3636
# dist: precise
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<?php
2+
/**
3+
* Class CustomFieldsPermalink
4+
*
5+
* @package WordPress_Custom_Fields_Permalink
6+
*/
7+
8+
/**
9+
* Class CustomFieldsPermalink provides the implementation of custom post fields in permalinks.
10+
*/
11+
class CustomFieldsPermalink {
12+
13+
const PARAM_CUSTOMFIELD_KEY = 'custom_field_key';
14+
const PARAM_CUSTOMFIELD_VALUE = 'custom_field_value';
15+
16+
/**
17+
* Do check against meta value or not.
18+
*
19+
* @var bool
20+
*/
21+
private static $check_custom_field_value = false;
22+
23+
/**
24+
* Filters the permalink structure for a post before token replacement occurs..
25+
* The pre_post_link filter implementation.
26+
*
27+
* @param string $permalink The site's permalink structure.
28+
* @param WP_Post $post The post in question.
29+
* @param bool $leavename Whether to keep the post name.
30+
*
31+
* @link https://developer.wordpress.org/reference/hooks/pre_post_link/
32+
*
33+
* @return mixed
34+
*/
35+
public static function link_post( $permalink, $post, $leavename ) {
36+
return self::link_rewrite_fields( $permalink, $post );
37+
}
38+
39+
/**
40+
* Filters the permalink for a post of a custom post type.
41+
* The post_type_link filter implementation.
42+
*
43+
* @param string $permalink The post's permalink.
44+
* @param WP_Post $post The post in question.
45+
* @param bool $leavename Whether to keep the post name.
46+
* @param bool $sample Is it a sample permalink.
47+
*
48+
* @link https://developer.wordpress.org/reference/hooks/post_type_link/
49+
*
50+
* @return mixed
51+
*/
52+
public static function link_post_type( $permalink, $post, $leavename, $sample ) {
53+
return self::link_rewrite_fields( $permalink, $post );
54+
}
55+
56+
/**
57+
* Rewrites permalink replacing custom fields.
58+
*
59+
* @param string $permalink The permalink.
60+
* @param WP_Post $post The post.
61+
*
62+
* @return string
63+
*/
64+
private static function link_rewrite_fields( $permalink, $post ) {
65+
$replace_callback = function ( $matches ) use ( &$post ) {
66+
return CustomFieldsPermalink::link_rewrite_fields_extract( $post, $matches[2] );
67+
};
68+
69+
return preg_replace_callback( '#(%field_(.*?)%)#', $replace_callback, $permalink );
70+
}
71+
72+
/**
73+
* Extract the metadata value from the post.
74+
*
75+
* @param WP_Post $post The post.
76+
* @param string $field_name The metadata key to extract.
77+
*
78+
* @return string
79+
*/
80+
private static function link_rewrite_fields_extract( $post, $field_name ) {
81+
$post_meta = get_post_meta( $post->ID );
82+
83+
if ( ! isset( $post_meta[ $field_name ] ) ) {
84+
return '';
85+
}
86+
87+
$value = $post_meta[ $field_name ][0];
88+
89+
$value = sanitize_title( $value );
90+
91+
return $value;
92+
}
93+
94+
/**
95+
* Filters the query variables whitelist before processing.
96+
* The query_vars filter implementation.
97+
*
98+
* @param array $public_query_vars The array of whitelisted query variables.
99+
*
100+
* @link https://developer.wordpress.org/reference/hooks/query_vars/
101+
*
102+
* @return mixed
103+
*/
104+
public static function register_extra_query_vars( $public_query_vars ) {
105+
array_push( $public_query_vars, self::PARAM_CUSTOMFIELD_KEY, self::PARAM_CUSTOMFIELD_VALUE );
106+
107+
return $public_query_vars;
108+
}
109+
110+
/**
111+
* Filters the array of parsed query variables.
112+
* The request filter implementation.
113+
*
114+
* @param array $query_vars The array of requested query variables.
115+
*
116+
* @link https://developer.wordpress.org/reference/hooks/request/
117+
*
118+
* @return mixed
119+
*/
120+
public static function process_request( $query_vars ) {
121+
// Additional parameters added to WordPress.
122+
// Main Loop query.
123+
if ( array_key_exists( self::PARAM_CUSTOMFIELD_KEY, $query_vars ) ) {
124+
$query_vars['meta_key'] = $query_vars[ self::PARAM_CUSTOMFIELD_KEY ];
125+
126+
// Remove temporary injected parameter.
127+
unset( $query_vars[ self::PARAM_CUSTOMFIELD_KEY ] );
128+
129+
// Do not check field's value for this moment.
130+
if ( true === self::$check_custom_field_value ) {
131+
if ( array_key_exists( self::PARAM_CUSTOMFIELD_VALUE, $query_vars ) ) {
132+
$query_vars['meta_value'] = $query_vars[ self::PARAM_CUSTOMFIELD_VALUE ];
133+
134+
// Remove temporary injected parameter.
135+
unset( $query_vars[ self::PARAM_CUSTOMFIELD_VALUE ] );
136+
}
137+
}
138+
}
139+
140+
return $query_vars;
141+
}
142+
143+
/**
144+
* Filters the full set of generated rewrite rules.
145+
* The rewrite_rules_array filter implementation.
146+
*
147+
* @param array $rules The compiled array of rewrite rules.
148+
*
149+
* @link https://developer.wordpress.org/reference/hooks/rewrite_rules_array/
150+
*
151+
* @return array
152+
*/
153+
public static function rewrite_rules_array_filter( $rules ) {
154+
$keys = array_keys( $rules );
155+
$tmp = $rules;
156+
$rules = array();
157+
158+
$j = sizeof( $keys );
159+
for ( $i = 0; $i < $j; ++ $i ) {
160+
$key = $keys[ $i ];
161+
162+
if ( preg_match( '/%field_([^%]*?)%/', $key ) ) {
163+
$key_new = preg_replace(
164+
'/%field_([^%]*?)%/',
165+
'([^/]+)',
166+
// You can simply add next group to the url, because WordPress.
167+
// Detect them automatically and add next $matches indices.
168+
$key
169+
);
170+
$rules[ $key_new ] = preg_replace(
171+
'/%field_([^%]*?)%/',
172+
sprintf( '%s=$1&%s=', self::PARAM_CUSTOMFIELD_KEY, self::PARAM_CUSTOMFIELD_VALUE ),
173+
// Here on the end will be pasted $matches[$i] from $keyNew,
174+
// so we can grab it it the future in self::PARAM_CUSTOMFIELD_VALUE parameter.
175+
$tmp[ $key ]
176+
);
177+
} else {
178+
$rules[ $key ] = $tmp[ $key ];
179+
}
180+
}
181+
182+
return $rules;
183+
}
184+
}

phpcs.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0"?>
2+
<ruleset name="WordPress Coding Standards for Plugins">
3+
<description>Generally-applicable sniffs for WordPress plugins</description>
4+
5+
<rule ref="WordPress-Core" />
6+
<rule ref="WordPress-Docs" />
7+
8+
<!-- Check all PHP files in directory tree by default. -->
9+
<arg name="extensions" value="php"/>
10+
<file>.</file>
11+
12+
<!-- Show progress and sniff codes in all reports -->
13+
<arg value="ps"/>
14+
15+
<exclude-pattern>*/node_modules/*</exclude-pattern>
16+
<exclude-pattern>*/vendor/*</exclude-pattern>
17+
</ruleset>

test/PermalinkAsserter.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/PermalinkSteps.php

Lines changed: 0 additions & 19 deletions
This file was deleted.

test/bootstrap.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
<?php
2+
/**
3+
* Tests bootstrap file.
4+
*
5+
* @package WordPress_Custom_Fields_Permalink
6+
*/
27

38
$_tests_dir = getenv( 'WP_TESTS_DIR' );
49

@@ -25,5 +30,5 @@ function _manually_load_plugin() {
2530
// Start up the WP testing environment.
2631
require $_tests_dir . '/includes/bootstrap.php';
2732

28-
require 'PermalinkSteps.php';
29-
require 'PermalinkAsserter.php';
33+
require 'class-permalinksteps.php';
34+
require 'class-permalinkasserter.php';

test/class-permalinkasserter.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Tests util file.
4+
*
5+
* @package WordPress_Custom_Fields_Permalink
6+
*/
7+
8+
/**
9+
* Class PermalinkAsserter contains utility methods to assert conditions related to permalinks.
10+
*/
11+
class PermalinkAsserter {
12+
13+
/**
14+
* Parent unit test case.
15+
*
16+
* @var WP_UnitTestCase
17+
*/
18+
private $unit_test_case;
19+
20+
/**
21+
* PermalinkAsserter constructor.
22+
*
23+
* @param WP_UnitTestCase $unit_test_case Parent unit test case.
24+
*/
25+
public function __construct( WP_UnitTestCase $unit_test_case ) {
26+
$this->unit_test_case = $unit_test_case;
27+
}
28+
29+
/**
30+
* Checks if post has an expected permalink.
31+
*
32+
* @param WP_Post $post The post.
33+
* @param string $permalink Expected permalink.
34+
*/
35+
public function has_permalink( $post, $permalink ) {
36+
$actual = wp_make_link_relative( get_the_permalink( $post ) );
37+
38+
$this->unit_test_case->assertEquals( $permalink, $actual );
39+
}
40+
}

test/class-permalinksteps.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
/**
3+
* Tests util file.
4+
*
5+
* @package WordPress_Custom_Fields_Permalink
6+
*/
7+
8+
/**
9+
* Class PermalinkSteps contains utility methods to arrange conditions related to permalinks.
10+
*/
11+
class PermalinkSteps {
12+
13+
/**
14+
* PermalinkSteps constructor.
15+
*/
16+
public function __construct() {
17+
}
18+
19+
/**
20+
* Sets the given permalink structure.
21+
*
22+
* @param string $structure The permalink structure.
23+
*/
24+
public function given_permalink_structure( $structure ) {
25+
global $wp_rewrite;
26+
27+
$wp_rewrite->init();
28+
$wp_rewrite->set_permalink_structure( $structure );
29+
$wp_rewrite->flush_rules();
30+
}
31+
32+
/**
33+
* Sets the "/%postname%/" permalink structure.
34+
*/
35+
public function given_postname_permalink_structure() {
36+
$this->given_permalink_structure( '/%postname%/' );
37+
}
38+
}

0 commit comments

Comments
 (0)