Guest User

WordPress VirtualMin installation script

a guest
Jun 19th, 2020
73
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. our (%in, %config);
  2.  
  3. # script_wordpress_desc()
  4. sub script_wordpress_desc
  5. {
  6. return "WordPress";
  7. }
  8.  
  9. sub script_wordpress_uses
  10. {
  11. return ( "php" );
  12. }
  13.  
  14. sub script_wordpress_longdesc
  15. {
  16. return "A semantic personal publishing platform with a focus on aesthetics, web standards, and usability.";
  17. }
  18.  
  19. # script_wordpress_versions()
  20. sub script_wordpress_versions
  21. {
  22. return ( "5.4.2" );
  23. }
  24.  
  25. sub script_wordpress_category
  26. {
  27. return ("Blog", "CMS");
  28. }
  29.  
  30. sub script_wordpress_php_vers
  31. {
  32. return ( 5 );
  33. }
  34.  
  35. sub script_wordpress_php_modules
  36. {
  37. return ("mysql", "gd");
  38. }
  39.  
  40. sub script_wordpress_php_optional_modules
  41. {
  42. return ("curl");
  43. }
  44.  
  45. sub script_wordpress_dbs
  46. {
  47. return ("mysql");
  48. }
  49.  
  50. sub script_wordpress_release
  51. {
  52. return 5;   # Fix format of wp-config.php
  53. }
  54.  
  55. # script_wordpress_depends(&domain, version)
  56. sub script_wordpress_depends
  57. {
  58. my ($d, $ver, $sinfo, $phpver) = @_;
  59. my @rv;
  60.  
  61. # Check for PHP 5.6.20+
  62. my $phpv = get_php_version($phpver || 5, $d);
  63. if (!$phpv) {
  64.     push(@rv, "Could not work out exact PHP version");
  65.     }
  66. elsif (&compare_versions($phpv, "5.6.20") < 0) {
  67.     push(@rv, "Wordpress requires PHP version 5.6.20 or later");
  68.     }
  69.  
  70. return @rv;
  71. }
  72.  
  73. # script_wordpress_params(&domain, version, &upgrade-info)
  74. # Returns HTML for table rows for options for installing Wordpress
  75. sub script_wordpress_params
  76. {
  77. my ($d, $ver, $upgrade) = @_;
  78. my $rv;
  79. my $hdir = public_html_dir($d, 1);
  80. if ($upgrade) {
  81.     # Options are fixed when upgrading
  82.     my ($dbtype, $dbname) = split(/_/, $upgrade->{'opts'}->{'db'}, 2);
  83.     $rv .= ui_table_row("Database for WordPress tables", $dbname);
  84.     my $dir = $upgrade->{'opts'}->{'dir'};
  85.     $dir =~ s/^$d->{'home'}\///;
  86.     $rv .= ui_table_row("Install directory", $dir);
  87.     }
  88. else {
  89.     # Show editable install options
  90.     my @dbs = domain_databases($d, [ "mysql" ]);
  91.     $rv .= ui_table_row("Database for WordPress tables",
  92.              ui_database_select("db", undef, \@dbs, $d, "wordpress"));
  93.     $rv .= ui_table_row("Install sub-directory under <tt>$hdir</tt>",
  94.                ui_opt_textbox("dir", &substitute_scriptname_template("wordpress", $d), 30, "At top level"));
  95.     if (&has_wordpress_cli()) {
  96.         # Can select the blog title
  97.         $rv .= ui_table_row("WordPress Blog title",
  98.             ui_textbox("title", $d->{'owner'}, 40));
  99.         }
  100.     }
  101. return $rv;
  102. }
  103.  
  104. # script_wordpress_parse(&domain, version, &in, &upgrade-info)
  105. # Returns either a hash ref of parsed options, or an error string
  106. sub script_wordpress_parse
  107. {
  108. my ($d, $ver, $in, $upgrade) = @_;
  109. if ($upgrade) {
  110.     # Options are always the same
  111.     return $upgrade->{'opts'};
  112.     }
  113. else {
  114.     my $hdir = public_html_dir($d, 0);
  115.     $in{'dir_def'} || $in{'dir'} =~ /\S/ && $in{'dir'} !~ /\.\./ ||
  116.         return "Missing or invalid installation directory";
  117.     my $dir = $in{'dir_def'} ? $hdir : "$hdir/$in{'dir'}";
  118.     my ($newdb) = ($in->{'db'} =~ s/^\*//);
  119.     return { 'db' => $in->{'db'},
  120.          'newdb' => $newdb,
  121.          'dir' => $dir,
  122.          'dbtbpref' => $in->{'dbtbpref'},
  123.          'path' => $in{'dir_def'} ? "/" : "/$in{'dir'}",
  124.          'title' => $in{'title'} };
  125.     }
  126. }
  127.  
  128. # script_wordpress_check(&domain, version, &opts, &upgrade-info)
  129. # Returns an error message if a required option is missing or invalid
  130. sub script_wordpress_check
  131. {
  132. local ($d, $ver, $opts, $upgrade) = @_;
  133. $opts->{'dir'} =~ /^\// || return "Missing or invalid install directory";
  134. $opts->{'db'} || return "Missing database";
  135. if (-r "$opts->{'dir'}/wp-login.php") {
  136.     return "WordPress appears to be already installed in the selected directory";
  137.     }
  138. $opts->{'dbtbpref'} =~ s/^\s+|\s+$//g;
  139. $opts->{'dbtbpref'} = 'wp_' if (!$opts->{'dbtbpref'});
  140. $opts->{'dbtbpref'} =~ /^\w+$/ || return "Database table prefix either not set or contains invalid characters";
  141. $opts->{'dbtbpref'} .= "_" if($opts->{'dbtbpref'} !~ /_$/);
  142. my ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
  143. my $clash = find_database_table($dbtype, $dbname, "$opts->{'dbtbpref'}.*");
  144. $clash && return "WordPress appears to be already using \"$opts->{'dbtbpref'}\" database table prefix";
  145. return undef;
  146. }
  147.  
  148. # script_wordpress_files(&domain, version, &opts, &upgrade-info)
  149. # Returns a list of files needed by Wordpress, each of which is a hash ref
  150. # containing a name, filename and URL
  151. sub script_wordpress_files
  152. {
  153. my ($d, $ver, $opts, $upgrade) = @_;
  154. if ($d && &has_wordpress_cli($opts) && !$opts->{'nocli'}) {
  155.     # Nothing to download
  156.     return ( );
  157.     }
  158. my @files = ( { 'name' => "source",
  159.        'file' => "wordpress-$ver.zip",
  160.        'url' => "http://wordpress.org/latest.zip",
  161.        'virtualmin' => 1,
  162.        'nocache' => 1 } );
  163. return @files;
  164. }
  165.  
  166. sub script_wordpress_commands
  167. {
  168. return ("unzip");
  169. }
  170.  
  171. # script_wordpress_install(&domain, version, &opts, &files, &upgrade-info)
  172. # Actually installs WordPress, and returns either 1 and an informational
  173. # message, or 0 and an error
  174. sub script_wordpress_install
  175. {
  176. local ($d, $version, $opts, $files, $upgrade, $domuser, $dompass) = @_;
  177. my ($out, $ex);
  178. if ($opts->{'newdb'} && !$upgrade) {
  179.         my $err = create_script_database($d, $opts->{'db'});
  180.         return (0, "Database creation failed : $err") if ($err);
  181.         }
  182. my ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
  183. my $dbuser = $dbtype eq "mysql" ? mysql_user($d) : postgres_user($d);
  184. my $dbpass = $dbtype eq "mysql" ? mysql_pass($d) : postgres_pass($d, 1);
  185. my $dbphptype = $dbtype eq "mysql" ? "mysql" : "psql";
  186. my $dbhost = get_database_host($dbtype, $d);
  187. my $dberr = check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
  188. return (0, "Database connection failed : $dberr") if ($dberr);
  189.  
  190. if (&has_wordpress_cli($opts) && !$opts->{'nocli'}) {
  191.     my $wp = "cd ".quotemeta($opts->{'dir'}).
  192.              " && ".&has_wordpress_cli($opts);
  193.     if (!$upgrade) {
  194.         # Execute the download command
  195.         &make_dir_as_domain_user($d, $opts->{'dir'}, 0755);
  196.         my $out = &run_as_domain_user($d, "$wp core download --version=$version 2>&1");
  197.         if ($? && $out !~ /Success:\s+WordPress\s+downloaded/i) {
  198.             return (-1, "wp core download failed : $out");
  199.             }
  200.  
  201.         # Configure the database
  202.         my $out = &run_as_domain_user($d,
  203.             "$wp config create --dbname=".quotemeta($dbname).
  204.             " --dbuser=".quotemeta($dbuser)." --dbpass=".quotemeta($dbpass).
  205.             " --dbhost=".quotemeta($dbhost)." 2>&1");
  206.         if ($?) {
  207.             return (-1, "wp config create failed : $out");
  208.             }
  209.        
  210.         # Set db prefix
  211.         my $out = &run_as_domain_user($d,
  212.             "$wp config set table_prefix $opts->{'dbtbpref'}".
  213.             " --type=variable".
  214.             " --path=".$opts->{'dir'});
  215.         if ($?) {
  216.             return (-1, "wp config set table_prefix failed : $out");
  217.             }
  218.  
  219.         # Do the install
  220.         my $out = &run_as_domain_user($d,
  221.             "$wp core install --url=$d->{'dom'}$opts->{'path'}".
  222.             " --title=".quotemeta($opts->{'title'} || $d->{'owner'}).
  223.             " --admin_user=".quotemeta($domuser).
  224.             " --admin_password=".quotemeta($dompass).
  225.             " --admin_email=".quotemeta($d->{'emailto'})." 2>&1");
  226.         if ($?) {
  227.             return (-1, "wp core install failed : $out");
  228.             }
  229.         }
  230.     else {
  231.         # Do the upgrade
  232.         my $out = &run_as_domain_user($d,
  233.                         "$wp core upgrade --version=$version 2>&1");
  234.         if ($?) {
  235.             return (-1, "wp core upgrade failed : $out");
  236.             }
  237.         }
  238.     }
  239. else {
  240.     # Extract tar file to temp dir and copy to target
  241.     my $verdir = "wordpress";
  242.     my $temp = transname();
  243.     my $err = extract_script_archive($files->{'source'}, $temp, $d,
  244.                          $opts->{'dir'}, $verdir);
  245.     $err && return (0, "Failed to extract source : $err");
  246.     my $cfileorig = "$opts->{'dir'}/wp-config-sample.php";
  247.     my $cfile = "$opts->{'dir'}/wp-config.php";
  248.  
  249.     # Create the 'wordpress' virtuser, if missing
  250.     if ($config{'mail'} && $d->{'mail'}) {
  251.         my ($wpvirt) = grep { $_->{'from'} eq 'wordpress@'.$d->{'dom'} }
  252.                        list_virtusers();
  253.         if (!$wpvirt) {
  254.             $wpvirt = { 'from' => 'wordpress@'.$d->{'dom'},
  255.                     'to' => [ $d->{'emailto_addr'} ] };
  256.             create_virtuser($wpvirt);
  257.             }
  258.         }
  259.  
  260.     # Copy and update the config file
  261.     if (!-r $cfile) {
  262.         run_as_domain_user($d, "cp ".quotemeta($cfileorig)." ".
  263.                           quotemeta($cfile));
  264.         my $lref = read_file_lines_as_domain_user($d, $cfile);
  265.         foreach my $l (@$lref) {
  266.             if ($l =~ /^define\(\s*'DB_NAME',/) {
  267.                 $l = "define('DB_NAME', '$dbname');";
  268.                 }
  269.             if ($l =~ /^define\(\s*'DB_USER',/) {
  270.                 $l = "define('DB_USER', '$dbuser');";
  271.                 }
  272.             if ($l =~ /^define\(\s*'DB_HOST',/) {
  273.                 $l = "define('DB_HOST', '$dbhost');";
  274.                 }
  275.             if ($l =~ /^define\(\s*'DB_PASSWORD',/) {
  276.                 $l = "define('DB_PASSWORD', '".
  277.                      php_quotemeta($dbpass, 1)."');";
  278.                 }
  279.             if ($l =~ /define\(\s*'(AUTH_KEY|SECURE_AUTH_KEY|LOGGED_IN_KEY|NONCE_KEY|AUTH_SALT|SECURE_AUTH_SALT|LOGGED_IN_SALT|NONCE_SALT)'/) {
  280.                 my $salt = random_password(64);
  281.                 $l = "define('$1', '$salt');";
  282.                 }
  283.             if ($l =~ /^define\(\s*'WP_AUTO_UPDATE_CORE',/) {
  284.                 $l = "define('WP_AUTO_UPDATE_CORE', false);";
  285.                 }
  286.             if ($l =~ /^\$table_prefix/) {
  287.                 $l = "\$table_prefix = '" . $opts->{'dbtbpref'} . "';";
  288.                 }
  289.             }
  290.         flush_file_lines_as_domain_user($d, $cfile);
  291.         }
  292.     }
  293.  
  294. # Make content directory writable, for uploads
  295. make_file_php_writable($d, "$opts->{'dir'}/wp-content", 0);
  296.  
  297. if (&has_wordpress_cli($opts) && !$opts->{'nocli'}) {
  298.     # Install is all done, return the base URL
  299.     my $url = script_path_url($d, $opts);
  300.     my $rp = $opts->{'dir'};
  301.     $rp =~ s/^$d->{'home'}\///;
  302.     return (1, "WordPress installation complete. It can be accessed at <a target=_blank href='$url'>$url</a>.", "Under $rp using $dbphptype database $dbname", $url, $domuser, $dompass);
  303.     }
  304. else {
  305.     # Return a URL to complete the install
  306.     my $url = script_path_url($d, $opts).
  307.              ($upgrade ? "wp-admin/upgrade.php" : "wp-admin/install.php");
  308.     my $userurl = script_path_url($d, $opts);
  309.     my $rp = $opts->{'dir'};
  310.     $rp =~ s/^$d->{'home'}\///;
  311.     return (1, "WordPress initial installation complete. It can be completed at <a target=_blank href='$url'>$url</a>.", "Under $rp using $dbphptype database $dbname", $userurl);
  312.     }
  313. }
  314.  
  315. # script_wordpress_uninstall(&domain, version, &opts)
  316. # Un-installs a Wordpress installation, by deleting the directory and database.
  317. # Returns 1 on success and a message, or 0 on failure and an error
  318. sub script_wordpress_uninstall
  319. {
  320. my ($d, $version, $opts) = @_;
  321.  
  322. # Remove the contents of the target directory
  323. my $derr = delete_script_install_directory($d, $opts);
  324. return (0, $derr) if ($derr);
  325.  
  326. # Remove all wp_ tables from the database
  327. cleanup_script_database($d, $opts->{'db'}, $opts->{'dbtbpref'});
  328.  
  329. # Take out the DB
  330. if ($opts->{'newdb'}) {
  331.         delete_script_database($d, $opts->{'db'});
  332.         }
  333.  
  334. return (1, "WordPress directory and tables deleted.");
  335. }
  336.  
  337. # script_wordpress_realversion(&domain, &opts)
  338. # Returns the real version number of some script install, or undef if unknown
  339. sub script_wordpress_realversion
  340. {
  341. my ($d, $opts, $sinfo) = @_;
  342. my $lref = read_file_lines("$opts->{'dir'}/wp-includes/version.php", 1);
  343. foreach my $l (@$lref) {
  344.     if ($l =~ /wp_version\s*=\s*'([0-9\.]+)'/) {
  345.         return $1;
  346.         }
  347.     }
  348. return undef;
  349. }
  350.  
  351. # script_wordpress_latest(version)
  352. # Returns a URL and regular expression or callback func to get the version
  353. sub script_wordpress_latest
  354. {
  355. my ($ver) = @_;
  356. return ( "http://wordpress.org/download/",
  357.      "Download\\s+WordPress\\s+([0-9\\.]+)" );
  358. }
  359.  
  360. sub script_wordpress_site
  361. {
  362. return 'http://wordpress.org/';
  363. }
  364.  
  365. sub script_wordpress_gpl
  366. {
  367. return 1;
  368. }
  369.  
  370. sub script_wordpress_passmode
  371. {
  372. return &has_wordpress_cli() ? 1 : 0;
  373. }
  374.  
  375. sub has_wordpress_cli
  376. {
  377. my ($opts) = @_;
  378. my $wp = &has_command("wp");
  379. return undef if (!$wp);
  380. return $wp if (!$opts);
  381. my $cli = &get_php_cli_command($opts->{'phpver'});
  382. return $wp if (!$cli);
  383. return $cli." ".$wp;
  384. }
  385.  
  386. 1;
RAW Paste Data