Finds the theme location and verifies the theme has all needed files
and is not obsoleted.

@param string $themename
@return string full dir path or null if not found
353271
private static function find_theme_location($themename) {
        global $CFG;

        if (file_exists("$CFG->dirroot/theme/$themename/config.php")) {
            $dir = "$CFG->dirroot/theme/$themename";

        } else if (!empty($CFG->themedir) and file_exists("$CFG->themedir/$themename/config.php")) {
            $dir = "$CFG->themedir/$themename";

        } else {
            return null;
        }

        if (file_exists("$dir/styles.php")) {
            //legacy theme - needs to be upgraded - upgrade info is displayed on the admin settings page
            return null;
        }

        return $dir;
    }
844731
protected function getBasePath(Theme $theme = null) : string
    {
        $theme = $theme ?? $this->getTheme();

        if (isset($this->fullPaths[$theme->getKey()])) {
            return $this->fullPaths[$theme->getKey()];
        }

        return $this->fullPaths[$theme->getKey()] = $this->createPath($theme->getPath(), $this->directory);
    }
1307649
protected function getThemesHierarchy($themeName)
    {
        $hierarchy = [];

        while (null !== $themeName) {
            $theme = $this->themeManager->getTheme($themeName);

            $hierarchy[] = $theme;
            $themeName   = $theme->getParentTheme();
        }

        return array_reverse($hierarchy);
    }
272275
private static function find_theme_config($themename, $settings, $parentscheck = true) {
        // We have to use the variable name $THEME (upper case) because that
        // is what is used in theme config.php files.

        if (!$dir = theme_config::find_theme_location($themename)) {
            return null;
        }

        $THEME = new stdClass();
        $THEME->name     = $themename;
        $THEME->dir      = $dir;
        $THEME->settings = $settings;

        global $CFG; // just in case somebody tries to use $CFG in theme config
        include("$THEME->dir/config.php");

        // verify the theme configuration is OK
        if (!is_array($THEME->parents)) {
            // parents option is mandatory now
            return null;
        } else {
            // We use $parentscheck to only check the direct parents (avoid infinite loop).
            if ($parentscheck) {
                // Find all parent theme configs.
                foreach ($THEME->parents as $parent) {
                    $parentconfig = theme_config::find_theme_config($parent, $settings, false);
                    if (empty($parentconfig)) {
                        return null;
                    }
                }
            }
        }

        return $THEME;
    }
517253
public function getViewsLocation($resourceName = null)
    {
        $resourceName = $resourceName ?? $this->resourceName;
        return $this->module.$this->theme.$resourceName;
    }
753918
final public static function spaceName(string $fullName = null): string
    {
        $fullName = $fullName ?: self::fullName();
        $fullName = \str_replace('\\', '/', $fullName);

        return \strpos($fullName, '/') ? \dirname($fullName) : null;
    }
428602
public function locate($filename)
    {
        $basename = preg_replace('~\.[^.]+$~', '', basename($filename));

        if (isset($this->map[$basename])) {
            return $this->root . '/' . $this->map[$basename];
        }

        return null;
    }
1139392
public function getRegions($themeName)
    {
        $translator = $this->getTranslator();
        $options = $this->getModuleOptions();
        $theme = $options->getThemeByName($themeName);
        $map = [];

        if (! isset($theme['frontend']['regions'])
            || ! is_array($theme['frontend']['regions'])
            || empty($theme['frontend']['regions'])
        ) {
            return $map;
        }
        $regions = $theme['frontend']['regions'];
        $widgets = array_keys($options->getWidgets());

        foreach ($regions as $regionName => $regionOptions) {
            if (isset($regionOptions['contains'])
                && is_array($regionOptions['contains'])
            ) {
                $container = $regionOptions['contains'];
                foreach ($container as $widget) {
                    $map[$widget] = $regionName;
                }
            }
        }
        foreach ($widgets as $widget) {
            if (! array_key_exists($widget, $map)) {
                $map[$widget] = 'none';
            }
        }
        return $map;
    }
404212
private function getPath()
	{
		$themesPath = $this->themesPath;											//  Basic Themes Path
		if( $this->themeName )														//  Theme Path is set
			$themesPath .= $this->themeName;										//  add Theme Path
		if( $this->cssFolder )														//  CSS Folder is set
			$themesPath .= $this->cssFolder;										//  add CSS Folder
		if( $this->mediumPath )														//  Medium Path is set
			$themesPath .= $this->mediumPath;										//  add Medium Path
		return $themesPath;
	}
413035
public function mkdir(string $dirName): bool
    {
        return mkdir($this->fileInfo->getAbsoluteFilePath() . MDir::getSeparator() . $dirName);
    }
1205321
public function getFullPath($filename = null)
    {
        if (!$filename) {
            $filename = $this->Filename;
        }
        return DMS::inst()->getStoragePath() . DIRECTORY_SEPARATOR . $this->Folder . DIRECTORY_SEPARATOR . $filename;
    }
1198537
public static function load($themename) {
        global $CFG;

        // load theme settings from db
        try {
            $settings = get_config('theme_'.$themename);
        } catch (dml_exception $e) {
            // most probably moodle tables not created yet
            $settings = new stdClass();
        }

        if ($config = theme_config::find_theme_config($themename, $settings)) {
            return new theme_config($config);

        } else if ($themename == theme_config::DEFAULT_THEME) {
            throw new coding_exception('Default theme '.theme_config::DEFAULT_THEME.' not available or broken!');

        } else if ($config = theme_config::find_theme_config($CFG->theme, $settings)) {
            debugging('This page should be using theme ' . $themename .
                    ' which cannot be initialised. Falling back to the site theme ' . $CFG->theme, DEBUG_NORMAL);
            return new theme_config($config);

        } else {
            // bad luck, the requested theme has some problems - admin see details in theme config
            debugging('This page should be using theme ' . $themename .
                    ' which cannot be initialised. Nor can the site theme ' . $CFG->theme .
                    '. Falling back to ' . theme_config::DEFAULT_THEME, DEBUG_NORMAL);
            return new theme_config(theme_config::find_theme_config(theme_config::DEFAULT_THEME, $settings));
        }
    }
1354499
public function find($theme)
	{
		foreach ($this->paths as $path)
		{
			if (is_dir($path.$theme))
			{
				return $path.$theme.DS;
			}
		}

		return false;
	}
1320702
private function getTheme($themeName)
    {
        $theme = $this->themeRepository->findOneByName($themeName);
        if (null === $theme) {
            throw new NotFoundHttpException(sprintf('Theme with name "%s" not found', $themeName));
        }

        return $theme;
    }
136537
public function path($styleName)
	{
		return $this->attachedFile->getInterpolator()->interpolate($this->attachedFile->path, $this->attachedFile, $styleName);
	}
75067
public function getFilePath($fileName = null)
    {
        if ($fileName === null) {
            $fileName = $this->fileName;
        }

        return $this->theme->getPath().'/'.$this->getObjectTypeDirName().'/'.$fileName;
    }
370921
public function symlinkWithFindInherit($theme)
    {
        $trace = debug_backtrace();

        if (! isset($trace[1])) return;

        // change backslash to forward slash (for windows file system)
        $path = str_replace("\\", "/", array_get($trace[1], 'file'));

        $config = $this->getConfig();

        $link = preg_replace("#(public/{$config['themeDir']}/)[^/]+#", "$1{$theme}", $path);

        extract($this->arguments);
        extract($this->view->getShared());

        return require($link);
    }