bool f_is_callable(CVarRef v, bool syntax /* = false */, Variant name /* = null */) { if (v.isString()) { if (!name.isNull()) name = v; if (syntax) return true; string lowered = Util::toLower((const char *)v.toString()); size_t c = lowered.find("::"); if (c != 0 && c != string::npos && c+2 < lowered.size()) { string classname = lowered.substr(0, c); string methodname = lowered.substr(c+2); const ClassInfo *clsInfo = ClassInfo::FindClass(classname.c_str()); if (clsInfo && clsInfo->isDeclared()) { return clsInfo->hasMethod(methodname.c_str()); } return false; } return f_function_exists(v.toString()); } if (v.is(KindOfArray)) { Array arr = v.toArray(); if (arr.size() == 2 && arr.exists(0LL) && arr.exists(1LL)) { Variant v0 = arr.rvalAt(0LL); Variant v1 = arr.rvalAt(1LL); if (v0.is(KindOfObject)) { v0 = v0.toObject()->o_getClassName(); } if (v0.isString() && v1.isString()) { if (!name.isNull()) { name = v0.toString() + "::" + v1.toString(); } if (same(v0, "self") || same(v0, "parent")) { throw NotImplementedException("augmenting class scope info"); } const ClassInfo *clsInfo = ClassInfo::FindClass(v0.toString()); if (clsInfo && clsInfo->isDeclared()) { return clsInfo->hasMethod(v1.toString()); } return false; } } } if (!name.isNull()) { name = v.toString(); } return false; }
bool f_is_callable(CVarRef v, bool syntax /* = false */, Variant name /* = null */) { if (v.isString()) { if (!name.isNull()) name = v; if (syntax) return true; string lowered = Util::toLower((const char *)v.toString()); size_t c = lowered.find("::"); if (c != 0 && c != string::npos && c+2 < lowered.size()) { string classname = lowered.substr(0, c); string methodname = lowered.substr(c+2); return f_call_user_func(2, "class_exists", Array::Create(String(classname))) && ClassInfo::hasAccess(classname, methodname, true, false); } return f_function_exists(v.toString()); } if (v.is(KindOfArray)) { Array arr = v.toArray(); if (arr.size() == 2 && arr.exists(0LL) && arr.exists(1LL)) { Variant v0 = arr.rvalAt(0LL); Variant v1 = arr.rvalAt(1LL); Object obj; bool staticCall = false; if (v0.is(KindOfObject)) { obj = v0.toObject(); v0 = obj->o_getClassName(); } else if (v0.isString()) { if (!f_call_user_func(2, "class_exists", Array::Create(v0))) { return false; } staticCall = true; } if (v1.isString()) { string lowered = Util::toLower((const char *)v1.toString()); size_t c = lowered.find("::"); if (c != 0 && c != string::npos && c+2 < lowered.size()) { string name1 = Util::toLower((const char *)v0.toString()); string name2 = lowered.substr(0, c); if (name1 == name2 || ClassInfo::isSubClass(name1, name2, false)) { staticCall = true; v0 = name2; v1 = lowered.substr(c+2); } } } if (v0.isString() && v1.isString()) { if (!name.isNull()) { name = v0.toString() + "::" + v1.toString(); } if (same(v0, "self") || same(v0, "parent")) { throw NotImplementedException("augmenting class scope info"); } return ClassInfo::hasAccess(v0, v1, staticCall, !obj.isNull()); } } } if (!name.isNull()) { name = v.toString(); } return false; }
bool f_is_callable(CVarRef v, bool syntax /* = false */, Variant name /* = null */) { if (v.isString()) { if (!name.isNull()) name = v; if (syntax) return true; String str = v.toString(); int c = str.find("::"); if (c != 0 && c != String::npos && c + 2 < str.size()) { String classname = str.substr(0, c); String methodname = str.substr(c + 2); return f_class_exists(classname) && ClassInfo::HasAccess(classname, methodname, true, false); } return f_function_exists(str); } if (v.is(KindOfArray)) { Array arr = v.toArray(); if (arr.size() == 2 && arr.exists(0LL) && arr.exists(1LL)) { Variant v0 = arr.rvalAt(0LL); Variant v1 = arr.rvalAt(1LL); Object obj; bool staticCall = false; if (v0.is(KindOfObject)) { obj = v0.toObject(); v0 = obj->o_getClassName(); } else if (v0.isString()) { if (!f_class_exists(v0.toString())) { return false; } staticCall = true; } if (v1.isString()) { String str = v1.toString(); int c = str.find("::"); if (c != 0 && c != String::npos && c + 2 < str.size()) { String name1 = v0.toString(); String name2 = str.substr(0, c); ASSERT(name1.get() && name2.get()); if (name1->isame(name2.get()) || ClassInfo::IsSubClass(name1, name2, false)) { staticCall = true; v0 = name2; v1 = str.substr(c + 2); } } } if (v0.isString() && v1.isString()) { if (!name.isNull()) { name = v0.toString() + "::" + v1.toString(); } if (same(v0, s_self) || same(v0, s_parent)) { throw NotImplementedException("augmenting class scope info"); } return ClassInfo::HasAccess(v0, v1, staticCall, !obj.isNull()); } } } if (!name.isNull()) { name = v.toString(); } return false; }
bool TestExtFunction::test_function_exists() { VERIFY(f_function_exists("test")); VERIFY(f_function_exists("TEst")); VERIFY(!f_function_exists("fake")); return Count(true); }