Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/cli #10

Merged
merged 9 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
"browser": true,
"jquery": true
},
"globals": {
"wpCheckin": false
},
"extends": [ "plugin:@wordpress/eslint-plugin/recommended-with-formatting" ],
"rules": {
"import/no-extraneous-dependencies": "off"
"import/no-extraneous-dependencies": "off",
"camelcase": "off"
}
}
40 changes: 40 additions & 0 deletions lib/WCTokyo/WpCheckin/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,48 @@ class Bootstrap extends SingletonPattern {
*/
protected function init() {
Setting::get_instance();
Router::get_instance();
RestApi::get_instance();
if ( defined( 'WP_CLI' ) && WP_CLI ) {
\WP_CLI::add_command( 'checkin', Command::class );
}
// Register assets.
add_action( 'init', [ $this, 'register_assets' ] );
}

/**
* Register plugin assets.
*
* @return void
*/
public function register_assets() {
$path = dirname( __FILE__, 4 ) . '/wp-dependencies.json';
if ( ! file_exists( $path ) ) {
return;
}
$dependencies = json_decode( file_get_contents( $path ), true );
if ( ! $dependencies ) {
return;
}
foreach ( $dependencies as $dependency ) {
if ( empty( $dependency['path'] ) ) {
continue;
}
$handle = $dependency['handle'];
$hash = $dependency['hash'];
$url = wp_checkin_url( $dependency['path'] );
$deps = $dependency['deps'];
switch ( $dependency['ext'] ) {
case 'js':
wp_register_script( $handle, $url, $deps, $hash, [
'in_footer' => $dependency['footer'],
'strategy' => 'defer',
] );
break;
case 'css':
wp_register_style( $handle, $url, $deps, $hash, $dependency['media'] );
break;
}
}
}
}
5 changes: 5 additions & 0 deletions lib/WCTokyo/WpCheckin/FireBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
use Kreait\Firebase\Factory;
use Google\Cloud\Firestore\FirestoreClient;

/**
* Firebase connector
*
* @deprecated
*/
class FireBase extends Singleton {

protected $credential_file_path = '';
Expand Down
133 changes: 133 additions & 0 deletions lib/WCTokyo/WpCheckin/RestApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php

namespace WCTokyo\WpCheckin;


use WCTokyo\WpCheckin\Pattern\SingletonPattern;

/**
* REST API handler.
*/
class RestApi extends SingletonPattern {

/**
* {@inheritDoc}
*/
protected function init() {
add_action( 'init', [ $this, 'register_post' ] );
add_action( 'rest_api_init', [ $this, 'register_routes' ] );
}

/**
* Register post type for checkin log.
*
* @return void
*/
public function register_post() {
register_post_type( 'checkin-log', [
'public' => false,
'show_in_rest' => false,
'supports' => [ 'title', 'editor', 'slug' ],
'show_ui' => true,
'show_in_nav_menus' => false,
'show_in_admin_bar' => false,
'menu_icon' => 'dashicons-tickets-alt',
'labels' => [
'name' => _x( 'チェックイン記録', '', 'wp-checkin' ),
'singular_name' => _x( 'チェックイン記録', '', 'wp-checkin' ),
],
] );
}

/**
* Register REST API routes.
*
* @return void
*/
public function register_routes() {
register_rest_route( 'wp-checkin/v1', '/checkin/(?P<ticket_id>\d+)', [
'methods' => [ 'POST', 'GET', 'DELETE' ],
'callback' => [ $this, 'checkin' ],
'permission_callback' => '__return_true',
'args' => [
'ticket_id' => [
'required' => true,
'type' => 'integer',
'validate_callback' => function( $param ) {
return is_numeric( $param );
},
],
'auth_user' => [
'required' => true,
'type' => 'string',
'validate_callback' => function( $param ) {
return get_option( 'wordcamp_auth_user' ) === $param;
},
],
'auth_pass' => [
'required' => true,
'type' => 'string',
'validate_callback' => function( $param ) {
return get_option( 'wordcamp_auth_pass' ) === $param;
},
],
],
] );
}

/**
* Callback for REST API
*
* @param \WP_REST_Request $request Request object.
* @return \WP_Error|\WP_REST_Response
*/
public function checkin( \WP_REST_Request $request ) {
$ticket = Tickets::get( $request['ticket_id'] );
if ( ! $ticket ) {
return new \WP_Error( 'invalid_ticket', __( 'チケットが見つかりません。', 'wp-checkin' ), [
'status' => 404,
] );
}
$is_checked_in = Tickets::is_checked_in( $request['ticket_id'] );
switch ( $request->get_method() ) {
case 'POST':
if ( $is_checked_in ) {
return new \WP_Error( 'already_checked_in', __( 'チケットは既にチェックイン済みです。', 'wp-checkin' ), [
'status' => 400,
] );
}
$post_id = wp_insert_post( [
// translators: %1$d is ticket ID, %2$s is ticket owner name.
'post_title' => sprintf( __( '#%1$d %2$s', 'wp-checkin' ), $ticket[0], wp_checkin_ticket_owner( $ticket ) ),
'post_name' => $ticket[0],
'post_type' => 'checkin-log',
'post_date' => current_time( 'mysql' ),
'post_status' => 'publish',
] );
if ( is_wp_error( $post_id ) ) {
return $post_id;
}
return new \WP_REST_Response( [
'checked_in' => true,
] );
case 'GET':
return new \WP_REST_Response( [
'checked_in' => (bool) $is_checked_in,
] );
case 'DELETE':
if ( ! $is_checked_in ) {
return new \WP_Error( 'not_checked_in', __( 'チケットはチェックインされていません。', 'wp-checkin' ), [
'status' => 400,
] );
}
if ( wp_delete_post( $is_checked_in->ID, true ) ) {
return new \WP_REST_Response( [
'checked_in' => false,
] );
}
return new \WP_Error( 'failed_to_delete', __( 'チェックイン記録の削除に失敗しました。', 'wp-checkin' ), [
'status' => 500,
] );
}
}
}
114 changes: 114 additions & 0 deletions lib/WCTokyo/WpCheckin/Router.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

namespace WCTokyo\WpCheckin;


use WCTokyo\WpCheckin\Pattern\SingletonPattern;

/**
* URL router for plugin.
*
* This will overrides default routing system and display other template.
*/
class Router extends SingletonPattern {

/**
* Register hooks to generate rewrite rules.
*
* @return void
*/
protected function init() {
add_action( 'init', [ $this, 'add_rewrite_rules' ] );
add_filter( 'query_vars', [ $this, 'add_query_vars' ] );
add_action( 'pre_get_posts', [ $this, 'pre_get_posts' ] );
}

/**
* Add query var 'checkin' for rewrite rules.
*
* @param string[] $vars Default query vars
* @return string[]
*/
public function add_query_vars( $vars ) {
$vars[] = 'checkin';
return $vars;
}

/**
* Hijack query
*
* @param \WP_Query $wp_query
* @return void
*/
public function pre_get_posts( $wp_query ) {
$is_checkin = $wp_query->get( 'checkin' );
if ( ! get_query_var( 'checkin' ) || ! $wp_query->is_main_query() ) {
return;
}
if ( in_array( $is_checkin, [ 'archive', 'single' ], true ) ) {
$do_auth_header = true;
wp_enqueue_style( 'wp-checkin' );
// Load template and exit.
$args = [];
switch ( $is_checkin ) {
case 'archive':
$args = [
'title' => __( '登録済みのチケット', 'wp-checkin' ),
];
break;
case 'single':
wp_enqueue_script( 'wp-checkin-attendance' );
wp_localize_script( 'wp-checkin-attendance', 'wpCheckin', [
'user' => get_option( 'wordcamp_auth_user' ),
'pass' => get_option( 'wordcamp_auth_pass' ),
] );
$id = get_query_var( 'p' );
$args = [
// translators: %d is ticket ID.
'title' => sprintf( __( 'チケット: %d', 'wp-checkin' ), $id ),
'id' => get_query_var( 'p' ),
];
break;
}
// Create fake post.
$GLOBALS['post'] = new \WP_Post( (object) [
'ID' => 0,
'post_title' => $args['title'],
'post_status' => 'publish',
'comment_count' => 0,
] );
remove_action( 'wp_head', 'feed_links_extra', 3 );
// Do authorization header.
if ( $do_auth_header ) {
$this->do_authorization_header();
}
// Render hijacked template.
do_action( 'template_redirect' );
wp_checkin_template( 'template-parts/header', $args );
wp_checkin_template( 'template-parts/' . $is_checkin, $args );
wp_checkin_template( 'template-parts/footer', $args );
exit;
}
}

/**
* Register rewrite rules.
*
* @return void
*/
public function add_rewrite_rules() {
// Front archive.
add_rewrite_rule( '^checkin/?$', 'index.php?checkin=archive', 'top' );
add_rewrite_rule( '^checkin/page/(\d+)/?$', 'index.php?checkin=archive&paged=$matches[1]', 'top' );
add_rewrite_rule( '^checkin/ticket/(\d+)/?$', 'index.php?checkin=single&p=$matches[1]', 'top' );
}

/**
* Do authorization header.
*
* @return void
*/
public function do_authorization_header() {
// W.I.P
}
}
Loading
Loading