github.com/ddev/ddev@v1.23.2-0.20240519125000-d824ffe36ff3/pkg/ddevapp/magento.go (about)

     1  package ddevapp
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/ddev/ddev/pkg/archive"
     9  	"github.com/ddev/ddev/pkg/fileutil"
    10  	"github.com/ddev/ddev/pkg/nodeps"
    11  	"github.com/ddev/ddev/pkg/output"
    12  	"github.com/ddev/ddev/pkg/util"
    13  )
    14  
    15  // isMagentoApp returns true if the app is of type magento
    16  func isMagentoApp(app *DdevApp) bool {
    17  	ism1, err := fileutil.FgrepStringInFile(filepath.Join(app.AppRoot, app.Docroot, "README.md"), `Magento - Long Term Support`)
    18  	if err == nil && ism1 {
    19  		return true
    20  	}
    21  	return false
    22  }
    23  
    24  // isMagento2App returns true if the app is of type magento2
    25  func isMagento2App(app *DdevApp) bool {
    26  	ism2, err := fileutil.FgrepStringInFile(filepath.Join(app.AppRoot, app.Docroot, "..", "SECURITY.md"), `https://hackerone.com/`)
    27  	if err == nil && ism2 {
    28  		return true
    29  	}
    30  	return false
    31  }
    32  
    33  // createMagentoSettingsFile manages creation and modification of local.xml.
    34  func createMagentoSettingsFile(app *DdevApp) (string, error) {
    35  
    36  	if fileutil.FileExists(app.SiteSettingsPath) {
    37  		// Check if the file is managed by ddev.
    38  		signatureFound, err := fileutil.FgrepStringInFile(app.SiteSettingsPath, nodeps.DdevFileSignature)
    39  		if err != nil {
    40  			return "", err
    41  		}
    42  
    43  		// If the signature wasn't found, warn the user and return.
    44  		if !signatureFound {
    45  			util.Warning("%s already exists and is managed by the user.", app.SiteSettingsPath)
    46  			return "", nil
    47  		}
    48  	} else {
    49  		output.UserOut.Printf("No %s file exists, creating one", app.SiteSettingsPath)
    50  
    51  		content, err := bundledAssets.ReadFile("magento/local.xml")
    52  		if err != nil {
    53  			return "", err
    54  		}
    55  		templateVars := map[string]interface{}{"DBHostname": "db"}
    56  		err = fileutil.TemplateStringToFile(string(content), templateVars, app.SiteSettingsPath)
    57  		if err != nil {
    58  			return "", err
    59  		}
    60  	}
    61  
    62  	return app.SiteDdevSettingsFile, nil
    63  }
    64  
    65  // setMagentoSiteSettingsPaths sets the paths to settings.php for templating.
    66  func setMagentoSiteSettingsPaths(app *DdevApp) {
    67  	app.SiteSettingsPath = filepath.Join(app.AppRoot, app.Docroot, "app", "etc", "local.xml")
    68  }
    69  
    70  // magentoImportFilesAction defines the magento workflow for importing project files.
    71  func magentoImportFilesAction(app *DdevApp, uploadDir, importPath, extPath string) error {
    72  	destPath := app.calculateHostUploadDirFullPath(uploadDir)
    73  
    74  	// parent of destination dir should exist
    75  	if !fileutil.FileExists(filepath.Dir(destPath)) {
    76  		return fmt.Errorf("unable to import to %s: parent directory does not exist", destPath)
    77  	}
    78  
    79  	// parent of destination dir should be writable.
    80  	if err := os.Chmod(filepath.Dir(destPath), 0755); err != nil {
    81  		return err
    82  	}
    83  
    84  	// If the destination path exists, remove it as was warned
    85  	if fileutil.FileExists(destPath) {
    86  		if err := os.RemoveAll(destPath); err != nil {
    87  			return fmt.Errorf("failed to cleanup %s before import: %v", destPath, err)
    88  		}
    89  	}
    90  
    91  	if isTar(importPath) {
    92  		if err := archive.Untar(importPath, destPath, extPath); err != nil {
    93  			return fmt.Errorf("failed to extract provided archive: %v", err)
    94  		}
    95  
    96  		return nil
    97  	}
    98  
    99  	if isZip(importPath) {
   100  		if err := archive.Unzip(importPath, destPath, extPath); err != nil {
   101  			return fmt.Errorf("failed to extract provided archive: %v", err)
   102  		}
   103  
   104  		return nil
   105  	}
   106  
   107  	//nolint: revive
   108  	if err := fileutil.CopyDir(importPath, destPath); err != nil {
   109  		return err
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  // getMagentoUploadDirs will return the default paths.
   116  func getMagentoUploadDirs(_ *DdevApp) []string {
   117  	return []string{"media"}
   118  }
   119  
   120  // getMagento2UploadDirs will return the default paths.
   121  func getMagento2UploadDirs(_ *DdevApp) []string {
   122  	return []string{"media"}
   123  }
   124  
   125  // createMagento2SettingsFile manages creation and modification of app/etc/env.php.
   126  func createMagento2SettingsFile(app *DdevApp) (string, error) {
   127  
   128  	if fileutil.FileExists(app.SiteSettingsPath) {
   129  		// Check if the file is managed by ddev.
   130  		signatureFound, err := fileutil.FgrepStringInFile(app.SiteSettingsPath, nodeps.DdevFileSignature)
   131  		if err != nil {
   132  			return "", err
   133  		}
   134  
   135  		// If the signature wasn't found, warn the user and return.
   136  		if !signatureFound {
   137  			util.Warning("%s already exists and is managed by the user.", app.SiteSettingsPath)
   138  			return "", nil
   139  		}
   140  	} else {
   141  		output.UserOut.Printf("No %s file exists, creating one", app.SiteSettingsPath)
   142  
   143  		content, err := bundledAssets.ReadFile("magento/env.php")
   144  		if err != nil {
   145  			return "", err
   146  		}
   147  
   148  		templateVars := map[string]interface{}{"DBHostname": "db"}
   149  		err = fileutil.TemplateStringToFile(string(content), templateVars, app.SiteSettingsPath)
   150  		if err != nil {
   151  			return "", err
   152  		}
   153  	}
   154  
   155  	return app.SiteDdevSettingsFile, nil
   156  }
   157  
   158  // setMagento2SiteSettingsPaths sets the paths to settings.php for templating.
   159  func setMagento2SiteSettingsPaths(app *DdevApp) {
   160  	app.SiteSettingsPath = filepath.Join(app.AppRoot, app.Docroot, "..", "app", "etc", "env.php")
   161  }
   162  
   163  // magentoConfigOverrideAction is not currently required
   164  // as OpenMage allows PHP up to 8.3
   165  // See https://github.com/OpenMage/magento-lts#requirements
   166  //func magentoConfigOverrideAction(app *DdevApp) error {
   167  //	app.PHPVersion = nodeps.PHP74
   168  //	return nil
   169  //}
   170  
   171  // Magento2 2.4.6 requires php8.1/2 and MariaDB 10.6
   172  // https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/system-requirements.html
   173  func magento2ConfigOverrideAction(app *DdevApp) error {
   174  	app.PHPVersion = nodeps.PHP82
   175  	app.Database = DatabaseDesc{Type: nodeps.MariaDB, Version: nodeps.MariaDB106}
   176  	return nil
   177  }