php – Custom Plugin: How to Include Install Buttons of other 3rd Party Plugins?

My employer has over a dozen WP sites, and we keep creating more. I decided to develop a plugin with all of the functions, etc. that we use across all the sites. We also use 3rd party plugins (such as Gravity Forms) on pretty much all of the sites. I would like to add a section on my settings page that detects if these 3rd party plugins are installed and if not, then include an “Install” button. I know how to detect the plugins, but I’m stuck at the install/activate part of the ordeal.

In my code below, I am trying to install the Fillable PDFs plugin from the settings page. The paid plugin zip file is on our main server. Other plugins I can get the zip file links directly from WordPress.org. I found the functions code online, but all I’m getting is a fatal error.

On my settings page:

<table class="form-table">
    <tr valign="top">
        <th scope="row">Fillable PDFs</th>
        <td>
        <?php 
        $fpdf_plugin_slug = 'forgravity-fillablepdfs/fillablepdfs.php';
        $fpdf_zip_url = 'https://mywebsite.com/download-plugins/forgravity-fillablepdfs_2.2.4.zip';
        if ( !is_plugin_active( $fpdf_plugin_slug ) ) {
            echo '<span class="span_install_button"><form method="post">
                <input type="hidden" name="pluginSlug" value="'.$fpdf_plugin_slug.'">
                <input type="hidden" name="pluginZip" value="'.$fpdf_zip_url.'">
                <input type="submit" name="install_plugin" class="btn" value="Install Plugin" />
            </form></span>';
        } else {
            echo 'Installed';
        } ?>
        </td>
    </tr>
</table>

In my functions:

if ( isset($_POST("install_plugin"))) {
    add_action( 'init', 'eri_install_plugin');
}
function eri_install_plugin($plugin_slug, $plugin_zip) {
  $plugin_slug = $_POST('pluginSlug');
  $plugin_zip = $_POST('pluginZip');  
    
  echo 'Starting ...<br><br>';
   
  echo 'Check if new plugin is already installed - ';
  if ( is_plugin_installed( $plugin_slug ) ) {
    $installed = true;
  } else {
    echo 'it's not installed. Installing.';
    $installed = install_plugin( $plugin_zip );
  }
   
  if ( !is_wp_error( $installed ) && $installed ) {
    echo 'Activating new plugin.';
    $activate = activate_plugin( $plugin_slug );
     
    if ( is_null($activate) ) {
      echo '<br>Done! Everything went smooth.';
    }
  } else {
    echo 'Could not install the new plugin.';
  }
}
function is_plugin_installed( $slug ) {
  if ( ! function_exists( 'get_plugins' ) ) {
    require_once ABSPATH . 'wp-admin/includes/plugin.php';
  }
  $all_plugins = get_plugins();
   
  if ( !empty( $all_plugins($slug) ) ) {
    return true;
  } else {
    return false;
  }
}
function install_plugin( $plugin_zip ) {
  include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  wp_cache_flush();
   
  $upgrader = new Plugin_Upgrader();
  $installed = $upgrader->install( $plugin_zip );
 
  return $installed;
}

java – How to improve my console based bank system to include more OOP concepts?

im currently trying to improve my skills in java. I have created a simple console based bank system with four classes. A user interface, Account holder, abstract bank account class which account holder extends and finally a main to run the UI.

Basically i want to get some suggested improvements and ideas on how to improve it and maby implement some more OOP concepts.

Thanks for any suggestions


 public class Main {

    public static void main(String() args) {
        // TODO Auto-generated method stub
         Scanner myObj = new Scanner(System.in);
         
         UserInterface ui = new UserInterface(myObj);
         ui.start();
         

    }

}

public class UserInterface {
    private Scanner scanner;
    private AccountHolder accountHolder;
    private Map<String, AccountHolder> accounts;

    public UserInterface(Scanner scanner) {
        this.scanner = scanner;
        this.accounts = new HashMap<String, AccountHolder>();
    }
    
    public void start() {
        while(true) {
            System.out.println("Welcome to the bank please select from the options below by pressing the required number");
            System.out.println("1 - Create Account");
            System.out.println("2 - Log into account");
            System.out.println("3 - Quit");
            System.out.print("Please make a choice: ");
            String input = scanner.nextLine();
            switch(input) {
            case "1": 
                createAccount();
                break;
            case "2":
                login();
                break;
            case "3":
                System.exit(0);
                break;
            default:
                System.out.println("Invalid option");
                break;
            }       
        }
    }
    
    private void createAccount() {
        
        System.out.println("Please enter a username");
        String username = scanner.nextLine();
        System.out.println("Please enter a password");
        String password = scanner.nextLine();
        System.out.println("Please enter name:");
        String name = scanner.nextLine();
        System.out.println("Please enter address:");
        String address = scanner.nextLine();
        System.out.println("Please enter mobile number:");
        String number = scanner.nextLine();
        System.out.println("Please enter an initial deposit ammount");
        double deposit = scanner.nextDouble();
        
        accountHolder = new AccountHolder(username, password, name, address, number, deposit);
        accounts.put(username, accountHolder);
        scanner.nextLine();
    }
    
    private void login() {
        System.out.println("Please enter your username");
        String username = scanner.nextLine();
        System.out.println("Please enter your password");
        String password = scanner.nextLine();
        
        if(accounts.containsKey(username)) {
            accountHolder = accounts.get(username);
            if(accountHolder.getPassword().equals(password)) {
                
                while(true) {
                    System.out.println("Please make a choice");
                    System.out.println("1 - Deposit");
                    System.out.println("2 - Withdraw");
                    System.out.println("3 - Balance");
                    System.out.println("4 - User information");
                    System.out.println("5 - Logout");
                    System.out.print("Please make a choice: ");
                    
                    String choice = scanner.nextLine();
                    switch(choice) {
                    case "1": 
                        System.out.println("Please enter an ammount to deposit");
                        double deposit = scanner.nextDouble();
                        accountHolder.deposit(deposit);
                        break;
                    case "2":
                        System.out.println("Please enter an ammount to withdraw");
                        double withdraw = scanner.nextDouble();
                        accountHolder.withdraw(withdraw);
                        break;
                    case "3":
                        System.out.println("Your current balance is: " + accountHolder.getBalance());
                        break;
                    case "4":
                        System.out.println(accountHolder);
                        break;
                    case "5":
                        System.exit(0);
                        break;
                    default:
                        System.out.println("Invalid option");
                            
                    }       
                }
                
                
                
            }
        }
    
    }


}
public class AccountHolder extends BankAccount {

    
    private String username;
    private String password;
    private String name;
    private String address;
    private String mobileNumber;
    private double deposit;
    
    
    
    

    public AccountHolder(String username, String password, String name, String address, String mobileNumber, double deposit) {
        this.username = username;
        this.password = password;
        this.name = name;
        this.address = address;
        this.mobileNumber = mobileNumber;
        this.deposit = deposit;


    }

    
    
    public String getName() {
        return this.name;
    }

    public String getAddress() {
        return this.address;
    }

    public String getNumber() {
        return this.mobileNumber;
    }
    
    public String getusername() {
        return this.username;
    }
    public String getPassword() {
        return this.password;
    }



    @Override
    double getBalance() {
        // TODO Auto-generated method stub
        return this.deposit += super.balance;
    }
    
    
    public String toString() {
        return this.name +  "n" + this.address+  "n" + this.mobileNumber+  "n" + super.getRandomAccountNumber()+  "n" + super.getRandomSortcode();
    }
}


public abstract class BankAccount {
    
    protected double balance;
    
    public BankAccount() {
        
        this.balance = 0;
        this.sortcode = "";
        this.accountNumber = "";
        
    }
    
    abstract double getBalance();

    public void withdraw(double moneyWithdrawn) {
    this.balance -= moneyWithdrawn;
    }
    public void deposit(double depositAmount) {
    this.balance += depositAmount;
    }
    
    public String getRandomSortcode() {
        Random rnd = new Random();
        int newSortcode = rnd.nextInt(999999);
        
        return String.format("%06d", newSortcode);
    }
    
    public String getRandomAccountNumber() {
        Random rnd = new Random();
        int newAccountNum = rnd.nextInt(999999);
        
        return String.format("%08d", newAccountNum);
    }
    
    
    
}

Include custom post type single template, but respect theme override of template if it exists

Through a plugin, I have created a custom post type named “my_custom”.

Also through the plugin, I am successfully including a template for the display of a “single” item of my custom post type:

function get_single_custom_template( $single_template ) {
    global $post;

    if ( 'my_custom' === $post->post_type ) {
            $single_template = PLUGIN_TEMPLATE_DIR . 'default-custom-single.php';
    }

    return $single_template;
}
add_filter( 'single_template', 'get_single_custom_template' ); 

This works as expected: my default-custom-single.php is displayed for a single entry of “my_custom” post type.

However, I want to be able to allow themes to override my default, and create their own template if desired.

How do I check whether there is a pre-existing custom-single.php in a theme and ONLY add my plugin-provided template if it doesn’t exist?

8 – Views exposed date filter using “Is between” doesn’t include end date

It’s a core bug, as @prkos mentioned, end time is assumed 00:00:00 when it needs to be 23:59:59

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_views_exposed_form_alter(&$form, DrupalCoreFormFormStateInterface $form_state, $form_id) {
  if (!empty($form('created')('max'))) {
    // use array_unshift() so custom submit runs before the default submit.
    array_unshift($form('#submit'), '_fix_max_date_submit_function');
  }
}

function _fix_max_date_submit_function($form, FormStateInterface $form_state) {
  $date_filter = $form_state->getValue('created');
  if ($date_filter('max')) {
    $date_filter('max') = $date_filter('max') . ' 23:59:59';
    $form_state->setValue('created', $date_filter);
  }
}

Alternative solution

You might have to use this solution if you don’t like the default Y-m-d formatting and rather have a m/d/Y input for example. Below I use Y-m-d, but you can always change it.

It’s a core bug, as @prkos mentioned, end time is assumed 12:00:00 AM when it needs to be 11:59:59 PM

If you enable Views sql query at /admin/structure/views/settings
you’ll see the query is like:

enter image description here

So all you have to do is swap the last timestamp with the corrected timestamp that takes 11:59:59 PM into account.

You can do that with hook_views_query_alter, but hold your horses, this hook can only run inside of mymodule.views_execution.inc file, so create that file and then you can do

<?php

use DrupalCoreDatetimeDrupalDateTime;
use DrupalviewsPluginviewsqueryQueryPluginBase;
use DrupalviewsViewExecutable;

/**
 * Implements hook_views_query_alter()
 */
function mymodule_talk_views_query_alter($view, $query) {
  if (!empty($query->where(1)('conditions'))) {
    foreach ($query->where(1)('conditions') as $con_key => $con_val) {
      $has_created_date_condition = strpos($con_val('field'), 'node_field_data.created') !== FALSE;
      if (($has_created_date_condition)) {
        // timezone set in /admin/config/regional/settings, will get "Users may set their own time zone" if checked.
        $timezone = date_default_timezone_get();

        $min_date = $view->exposed_data('created')('min');
        $min_date_obj = DrupalDateTime::createFromFormat('Y-m-d', $min_date, $timezone);
        $min_date_timestamp = $min_date_obj->getTimestamp();

        $max_date = $view->exposed_data('created')('max');
        $fixed_max_date_obj = DrupalDateTime::createFromFormat('Y-m-d h:i:s A', $max_date . ' 11:59:59 PM', $timezone);
        $fixed_max_date_timestamp = $fixed_max_date_obj->getTimestamp();

        $query->where(1)('conditions')($con_key)('field') = 'node_field_data.created';
        $query->where(1)('conditions')($con_key)('value')(0) = $min_date_timestamp;
        $query->where(1)('conditions')($con_key)('value')(1) = $fixed_max_date_timestamp;
        $query->where(1)('conditions')($con_key)('operator') = 'BETWEEN';
      }
    }
  }
}

magento2 – Sitemap and Product URLS to include a specific parent category in URL – Magento 2

I would like to use the “Use Categories Path for Product URLs” feature within Magento 2 however default to it. Not only that but in the case a product belongs to multiple categories be able to set the default path to include a “Master” category.

By default the sitemap seems to generate basic urls like domain.com/product.html. And even when “Use Categories Path for Product URLs” is set to enabled the products are accessible from other urls. I want to achieve domain.com/master-category/product.html as the only route to that product if possible.

Not sure the best route to achieve this weather it be a module that creates redirects based on master categories and generates URLS redirects accordingly and then similarly mods the sitemap generation to include these URLS or if there is an easier route e.g default settings or recommended module?

url rewriting – Include page name in posts slug

I have created a custom page template with option to select a tag from posts Categories to query the respective posts with that tag when the page is opened.

Page with name Trips are created, custom template selected and also category tag Trips is selected.

Page is then added to the menu under About Us menu item.

When I open the page site.com/about-us/trips/ A custom template are loaded with all the posts with term Trips.

When I open the post, the URL of the post is site.com/trips/post-slug where “trips” are the category tag slug.

Is there any option for those posts to include their “parent” page slugs like in this example it would be site.com/about-us/trips/post-slug ?
I could set the category base as ‘about-us’, but that is not a solution because there could be multiple pages with that custom template and another category tag selected f.e. site.com/about-us/interviews/post-slug

I am sorry, I have no code example for what I have done so far as I dont even know where to start :]

SharePoint conditional formatting rule only available for date, how to include time in the rule?

I’m new to SharePoint. I have a SP list for my schedule. I have overdue column that I would like to change background color based on Datetime column and status. The two column are Deadline and Status. The logic is, if datetime now > Deadline (including time) and status = PENDING, change background color to red. Means that its already overdue. I managed to change the background color to red by using conditional formatting function in the SP online. But it only filter based on date not including the time. I want it to include time as well as my Deadline column is a Datetime column. Any idea on how to do this?

Here is the screenshot of my SP:

enter image description here

As you can see above, the time have not passed yet but the column color already turn red because its only filter the date.

Here is the JSON for the conditional formatting:

{
  "elmType": "div",
  "style": {
    "box-sizing": "border-box",
    "padding": "0 2px"
  },
  "attributes": {
    "class": {
      "operator": ":",
      "operands": (
        {
          "operator": "&&",
          "operands": (
            {
              "operator": "<=",
              "operands": (
                {
                  "operator": "Date()",
                  "operands": (
                    {
                      "operator": "toDateString()",
                      "operands": (
                        {
                          "operator": "Date()",
                          "operands": (
                            "($Deadline)"
                          )
                        }
                      )
                    }
                  )
                },
                {
                  "operator": "Date()",
                  "operands": (
                    {
                      "operator": "toDateString()",
                      "operands": (
                        {
                          "operator": "Date()",
                          "operands": (
                            "@now"
                          )
                        }
                      )
                    }
                  )
                }
              )
            },
            {
              "operator": "==",
              "operands": (
                "($Status)",
                "PENDING"
              )
            }
          )
        },
        "sp-css-backgroundColor-blockingBackground50",
        {
          "operator": ":",
          "operands": (
            {
              "operator": "==",
              "operands": (
                "($Status)",
                "COMPLETED"
              )
            },
            "sp-css-backgroundColor-successBackground30",
            ""
          )
        }
      )
    }
  },
  "children": (
    {
      "elmType": "span",
      "style": {
        "line-height": "16px",
        "height": "14px"
      },
      "attributes": {
        "iconName": {
          "operator": ":",
          "operands": (
            {
              "operator": "&&",
              "operands": (
                {
                  "operator": "<=",
                  "operands": (
                    {
                      "operator": "Date()",
                      "operands": (
                        {
                          "operator": "toDateString()",
                          "operands": (
                            {
                              "operator": "Date()",
                              "operands": (
                                "($Deadline)"
                              )
                            }
                          )
                        }
                      )
                    },
                    {
                      "operator": "Date()",
                      "operands": (
                        {
                          "operator": "toDateString()",
                          "operands": (
                            {
                              "operator": "Date()",
                              "operands": (
                                "@now"
                              )
                            }
                          )
                        }
                      )
                    }
                  )
                },
                {
                  "operator": "==",
                  "operands": (
                    "($Status)",
                    "PENDING"
                  )
                }
              )
            },
            "",
            {
              "operator": ":",
              "operands": (
                {
                  "operator": "==",
                  "operands": (
                    "($Status)",
                    "COMPLETED"
                  )
                },
                "",
                ""
              )
            }
          )
        }
      }
    },
    {
      "elmType": "span",
      "style": {
        "overflow": "hidden",
        "text-overflow": "ellipsis",
        "padding": "0 3px"
      },
      "txtContent": "($Overdue)",
      "attributes": {
        "class": {
          "operator": ":",
          "operands": (
            {
              "operator": "&&",
              "operands": (
                {
                  "operator": "<=",
                  "operands": (
                    {
                      "operator": "Date()",
                      "operands": (
                        {
                          "operator": "toDateString()",
                          "operands": (
                            {
                              "operator": "Date()",
                              "operands": (
                                "($Deadline)"
                              )
                            }
                          )
                        }
                      )
                    },
                    {
                      "operator": "Date()",
                      "operands": (
                        {
                          "operator": "toDateString()",
                          "operands": (
                            {
                              "operator": "Date()",
                              "operands": (
                                "@now"
                              )
                            }
                          )
                        }
                      )
                    }
                  )
                },
                {
                  "operator": "==",
                  "operands": (
                    "($Status)",
                    "PENDING"
                  )
                }
              )
            },
            "",
            {
              "operator": ":",
              "operands": (
                {
                  "operator": "==",
                  "operands": (
                    "($Status)",
                    "COMPLETED"
                  )
                },
                "",
                ""
              )
            }
          )
        }
      }
    }
  )
}

Modify slider plugin’s get taxonomy to include custom taxonomy (years)

The below code allows me to customize my sliders by category. I have a custom taxonomy called “years” that I would like to include. Ultimately, I want to be able to make sliders by category and by years.

if( !function_exists('plugin_get_taxonomies') ){

    function plugin_get_taxonomies( $plugin_texonomy = 'category' ){
        $terms = get_terms( array(
            'taxonomy' => $plugin_texonomy,
            'hide_empty' => true,
        ));
        $options = array();
        if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
            foreach ( $terms as $term ) {
                $options( $term->slug ) = $term->name;
            }
            return $options;
        }
    }
}

oracle – Select parent rows and include cost of children

I have a WORKORDER table that has parent and child WOs in it:

with workorder as (
select 'WO37342' as wonum,      null as parent, 297.36 as actlabcost, 200 as actmatcost, 0 as actservcost, 0 as acttoolcost from dual
union all
select 'WO37427' as wonum, 'WO37342' as parent,  99.12 as actlabcost,   0 as actmatcost, 0 as actservcost, 0 as acttoolcost from dual
union all
select 'WO37429' as wonum, 'WO37342' as parent,  99.12 as actlabcost, 100 as actmatcost, 0 as actservcost, 0 as acttoolcost from dual
)
select
    * 
from
    workorder

 WONUM   PARENT  ACTLABCOST ACTMATCOST ACTSERVCOST ACTTOOLCOST
 ------- ------- ---------- ---------- ----------- -----------
 WO37342             297.36        200           0           0
 WO37427 WO37342      99.12          0           0           0
 WO37429 WO37342      99.12        100           0           0

I want to select the parent rows and include the cost of the children in the parents:

 WONUM    ACTLABCOST ACTMATCOST ACTSERVCOST ACTTOOLCOST
 ------- ----------- ---------- ----------- -----------
 WO37342       495.6        300           0           0

Is there a concise way of doing this with Oracle 18c SQL?