class Detector::Php::Phalcon

Defined in:

detector/detectors/php/phalcon.cr

Constant Summary

PHALCON_NAMESPACE_MARKERS = ["Phalcon\\Mvc\\Micro", "Phalcon\\Mvc\\Application", "Phalcon\\Mvc\\Controller", "Phalcon\\Mvc\\Router", "Phalcon\\Mvc\\Model", "Phalcon\\Di\\FactoryDefault", "Phalcon\\Di\\Di"]

Every reference below is namespace-qualified under Phalcon\, which no other PHP framework in this detector set spells. Unlike Laminas' detector (which has to avoid the generic word "Zend"), a plain substring match on the namespace is safe here.

PHALCON_PACKAGES = ["ext-phalcon", "phalcon/ide-stubs", "phalcon/incubator", "phalcon/devtools", "phalcon/migrations"]

Phalcon ships as a compiled C extension (pecl install phalcon, or a prebuilt .so/.dll), not a Composer dependency — there is no phalcon/cphalcon package on Packagist for composer.json to name. Real apps still declare the dependency in Composer via the standard ext-* platform-package convention, and the community ships a handful of auxiliary Composer packages alongside the extension: IDE stubs (editor autocompletion against the compiled extension), the incubator (community add-ons), devtools (code generators/CLI) and migrations.

PHP_INI_EXTENSION_RE = /extension\s*=\s*["']?phalcon(?:\.(?:so|dll))?["']?/i

extension=phalcon (optionally phalcon.so / phalcon.dll) enabling the compiled extension in php.ini — the way most real deployments actually declare this dependency, since Composer has no package for the extension itself.

Class Method Summary

Instance Method Summary

Instance methods inherited from class Detector

applicable?(filename : String) : Bool applicable?, base_relative_path(filename : String) : String base_relative_path, content_matches?(file_contents : String, markers : Regex) : Bool content_matches?, detect(filename : String, file_contents : String) : Bool detect, gemfile_dependency?(file_contents : String, gem_name : String) : Bool gemfile_dependency?, gemspec_dependency?(file_contents : String, gem_name : String) : Bool gemspec_dependency?, idempotent? : Bool idempotent?, logger : NoirLogger logger, name : String name, path_sensitive? : Bool path_sensitive?

Constructor methods inherited from class Detector

new(options : Hash(String, YAML::Any)) new

Macros inherited from class Detector

detector_for(tech, extensions = nil, basenames = nil, path_segments = nil, idempotent = nil) detector_for

Class Method Detail

def self.tech_name : String #

The tech name without needing an instance, so the registry can be read off the classes themselves rather than from a parallel list.


[View source]

Instance Method Detail

def applicable?(filename : String) : Bool #
Description copied from class Detector

Cheap filename-only filter the detector pass uses to skip #detect on files the detector cannot possibly match. The default true preserves prior behavior (every detector runs on every file). Override with the same predicate the body of #detect starts with — e.g., filename.ends_with?(".py") for a Python framework detector — so the detector loop avoids the #detect dispatch on files outside the detector's language.

On large codebases (saleor's 4255 .py files) this lifts ~100 virtual #detect calls per file out of the hot loop because most detectors' inner first-line is exactly this kind of cheap filename check.


[View source]
def detect(filename : String, file_contents : String) : Bool #

[View source]
def set_name #

[View source]