/// <summary> /// Adds session variables aliases to global variables. /// </summary> public void RegisterSessionGlobals() { PhpArray globals, session; // do not create session variables table if not exists: if ((session = PhpReference.AsPhpArray(AutoGlobals.Session)) == null) { return; } // creates globals array if it doesn't exists: globals = GlobalVariables; // iterates using unbreakable enumerator: foreach (KeyValuePair <IntStringKey, object> entry in session) { PhpReference php_ref = entry.Value as PhpReference; // converts the session variable to a reference if it is not one ("no duplicate pointers" rule preserved): if (php_ref == null) { session[entry.Key] = php_ref = new PhpReference(entry.Value); } // adds alias to the globals: globals[entry.Key] = php_ref; } }
/// <summary> /// Applies the new item access on a given variable (<B>ReadRef</B> semantics) that has already been ensured to /// be <see cref="PhpArray"/>. /// </summary> public override PhpReference GetEnsuredRef(object var, ScriptContext context, DTypeDesc caller) { PhpReference reference = new PhpReference(); ((PhpArray)var).Add(reference); return(reference); }
/// <summary> /// Applies the new item access on a given variable (<B>ReadRef</B> semantics). /// </summary> public override PhpReference GetRef(ref object var, ScriptContext context, DTypeDesc caller) { PhpReference reference = new PhpReference(); Operators.SetItem(reference, ref var); return(reference); }
/// <summary> /// Eliminates non-aliased <see cref="PhpReference"/>s. <seealso cref="WrapPropertyValue"/> /// </summary> /// <param name="val">The object to unwrap.</param> /// <returns><paramref name="val"/>'s value if it is a non-aliased <see cref="PhpReference"/>, or /// <paramref name="val"/> itself otherwise.</returns> internal static object UnwrapPropertyValue(object val) { PhpReference reference = val as PhpReference; if (reference != null && !reference.IsAliased) { return(reference.Value); } return(val); }
public static void SetValue(ref PhpReference variable, object value) { if (variable == null) { variable = new PhpReference(value); } else { variable.Value = value; } }
/// <summary> /// Ends session, i.e. stores content of the $_SESSION array to the <c>HttpContext.Session</c> collection. /// </summary> /// <param name="abandon">Whether to abandon the session without persisting variables.</param> /// <exception cref="SessionException">Session state not available.</exception> public void EndSession(bool abandon) { // checks and changes session state: if (disposed || sessionState != SessionStates.Started) { return; } sessionState = SessionStates.Closing; if (httpContext.Session == null) { throw new SessionException(CoreResources.GetString("session_state_unavailable")); } GlobalConfiguration global = Configuration.Global; PhpArray variables = PhpReference.AsPhpArray(scriptContext.AutoGlobals.Session); if (variables == null) { variables = new PhpArray(); } try { if (!abandon) { scriptContext.Config.Session.Handler.Persist(variables, scriptContext, httpContext); } else { scriptContext.Config.Session.Handler.Abandoning(scriptContext, httpContext); } } finally { if (!abandon) { // if ASP.NET session state is empty then adds a dump item to preserve the session: if (httpContext.Session.Count == 0) { httpContext.Session.Add(AspNetSessionHandler.PhpNetSessionVars, AspNetSessionHandler.DummySessionItem); } } else { // abandons ASP.NET session: httpContext.Session.Abandon(); } sessionState = SessionStates.Closed; } }
/// <summary> /// Adds variables from one auto-global array to another. /// </summary> /// <param name="dst">A PHP reference to the target array.</param> /// <param name="src">A PHP reference to the source array.</param> /// <remarks> /// Variable values are deeply copied. /// If either reference is a <B>null</B> reference or doesn't contain an array, no copying takes place. /// </remarks> internal static void AddVariables(PhpReference /*!*/ dst, PhpReference /*!*/ src) { if (dst != null && src != null) { PhpArray adst = dst.Value as PhpArray; PhpArray asrc = src.Value as PhpArray; if (adst != null && asrc != null) { AddVariables(adst, asrc); } } }
/// <summary> /// Evaluates this chain as if it had the <see cref="PHP.Core.AST.AccessType.ReadRef"/> access type. /// </summary> /// <param name="context">Current script context.</param> /// <returns>The result of chain evaluation.</returns> public PhpReference GetReference(ScriptContext context) { PhpReference reference; RuntimeChainElement element = Chain; if (element == null) { // if we are just wrapping the variable with a PhpReference, make a copy reference = Variable as PhpReference; if (reference == null) { reference = new PhpReference(PhpVariable.Copy(Variable, CopyReason.Unknown)); } return(reference); } // make sure that we have a PhpReference reference = PhpVariable.MakeReference(Variable); if (element == lastElement) { // GetPropertyRef/GetItemRef return(element.GetRef(ref reference.value, context, Caller)); } // EnsureVariableIsObject/EnsureVariableIsArray object var = element.EnsureVariable(ref reference.value, context, Caller); if (var == null) { return(new PhpReference()); } while (element.Next != null) { // Ensure{Field,Item}Is{Object,Array} var = element.Ensure(var, context, Caller); if (var == null) { return(new PhpReference()); } element = element.Next; } // GetObjectPropertyRef/GetArrayItemRef return(element.GetEnsuredRef(var, context, Caller)); }
public static T Call <T>(this ScriptContext context, string /*!*/ functionName, NamingContext namingContext, Dictionary <string, object> callerLocalVariables, params object[] arguments) where T : class { PhpReference rf = context.Call(functionName, namingContext, callerLocalVariables, arguments); if (rf.Value == null) { return(null); } else { return(DuckTyping.Instance.ImplementDuckType <T>(rf.Value)); } }
/// <summary> /// Starts session if not already started. Loads session variables from <c>HttpContext.Session</c>. /// </summary> /// <para> /// Session state (<c>HttpContext.Session</c>) has to be available at the time of the call. /// Otherwise, an exception occurs. /// </para> /// <para> /// Starting the session inheres in importing session variables from the session data store. /// The store is specific to the current PHP session handler /// defined by configuration option <see cref="LocalConfiguration.SessionSection.Handler"/>. /// In the case the ASP.NET handler is active, values from <c>HttpContext.Session</c> are imported to /// <c>$_SESSION</c> PHP auto-global variable. Hence, items added to the <c>HttpContext.Session</c> by /// non-PHP code after the start of the session will not be visible to PHP code. The <c>$_SESSION</c> variable /// has to be updated directly (see <c>ScriptContext.AutoGlobals</c>) to make these items visible to PHP. /// </para> /// <exception cref="SessionException">Session state not available.</exception> public void StartSession() { // checks and changes session state: if (disposed || sessionState != SessionStates.Closed) { return; } sessionState = SessionStates.Starting; if (httpContext.Session == null) { throw new SessionException(CoreResources.GetString("session_state_unavailable")); } EnsureSessionId(); GlobalConfiguration global = Configuration.Global; PhpArray variables = null; // removes dummy item keeping the session alive: if (httpContext.Session[AspNetSessionHandler.PhpNetSessionVars] as string == AspNetSessionHandler.DummySessionItem) { httpContext.Session.Remove(AspNetSessionHandler.PhpNetSessionVars); } // loads an array of session variables using the current session handler: variables = scriptContext.Config.Session.Handler.Load(scriptContext, httpContext); // variables cannot be null: if (variables == null) { variables = new PhpArray(); } // sets the auto-global variable (the previous content of $_SESSION array is discarded): PhpReference.SetValue(ref scriptContext.AutoGlobals.Session, variables); // copies session variables to $GLOBALS array if necessary: if (global.GlobalVariables.RegisterGlobals) { scriptContext.RegisterSessionGlobals(); } // adds a SID constant: UpdateSID(); sessionState = SessionStates.Started; }
/// <summary> /// Returns names and properties of all instance properties or only PHP fields (including runtime fields). /// </summary> /// <param name="instance">The instance being serialized.</param> /// <param name="phpFieldsOnly"><B>True</B> to return only PHP fields, <B>false</B> to return all /// instance properties.</param> /// <returns>Name-value pairs. Names are properly formatted for serialization.</returns> public static IEnumerable <KeyValuePair <string, object> > EnumerateSerializableProperties( DObject /*!*/ instance, bool phpFieldsOnly) { // enumerate CT properties: foreach (KeyValuePair <VariableName, DPropertyDesc> pair in instance.TypeDesc.EnumerateProperties()) { // skip static props if (pair.Value.IsStatic) { continue; } // skip CLR fields and props if asked so if (phpFieldsOnly && !(pair.Value is DPhpFieldDesc)) { continue; } object property_value = pair.Value.Get(instance); PhpReference property_value_ref = property_value as PhpReference; if (property_value_ref == null || property_value_ref.IsSet) { yield return(new KeyValuePair <string, object>( Serialization.FormatPropertyName(pair.Value, pair.Key.ToString()), property_value)); } } // enumerate RT fields: if (instance.RuntimeFields != null) { foreach (var pair in instance.RuntimeFields) { yield return(new KeyValuePair <string, object>(pair.Key.String, pair.Value)); } } }
public PhpReference PeekReferenceUnchecked(int i) { object item = Items[Top - i]; PhpReference result; PhpRuntimeChain php_chain; // the caller may not pushed a reference although the formal argument is a reference: // it doesn't matter if called by callback: if ((result = item as PhpReference) == null) { // caller may have pushed a runtime chain => evaluate it: if ((php_chain = item as PhpRuntimeChain) != null) { // call state has to be stored since chain can call arbitrary user code: CallState call_state = SaveCallState(); result = php_chain.GetReference(Context); RestoreCallState(call_state); } else { // the reason of copy is not exactly known (it may be returning by copy as well as passing by copy): result = new PhpReference(PhpVariable.Copy(item, CopyReason.Unknown)); // Reports an error in the case that we are not called by callback. // Although, this error is fatal one can switch throwing exceptions off. // If this is the case the afterwards behavior will be the same as if callback was called. if (!Callback) { // warning (can invoke user code => we have to save and restore callstate): CallState call_state = SaveCallState(); PhpException.ArgumentNotPassedByRef(i, CalleeName); RestoreCallState(call_state); } } } return(result); }
public PhpReference PeekReference(int i) { PhpReference result; if (ArgCount >= i) { // peeks the reference: result = PeekReferenceUnchecked(i); // stores the value back to the stack so that user args functions can work with it: Items[Top - i] = result; } else { result = new PhpReference(); // warning (can invoke user code => we have to save and restore callstate): CallState call_state = SaveCallState(); PhpException.MissingArgument(i, CalleeName); RestoreCallState(call_state); } return(result); }
private static void WriteAutoGlobal(TextWriter output, ScriptContext context, string name, PhpReference autoglobal) { PhpArray array; if ((array = autoglobal.Value as PhpArray) != null) { foreach (KeyValuePair <IntStringKey, object> entry in array) { HtmlVarRow(output, name, entry.Key.Object, entry.Value); } } }
/// <summary> /// Adds a level of indirection to a specified argument. /// Supresses checks that disables a reference to containe another reference. /// </summary> /// <param name="i">An index of argument starting from 1.</param> internal void AddIndirection(int i) { // preserves "no duplicate pointers" invariant: Items[Top - i] = new PhpReference(Items[Top - i], true); }
public static PhpArray AsPhpArray(PhpReference variable) { return(AsType <PhpArray>(variable)); }
public static T AsType <T>(PhpReference variable) where T : class { return((variable != null) ? variable.Value as T : null); }
protected override void SetArrayItemRefOverride(object key, PhpReference value) { ScriptContext.CurrentContext.AbortSetterChain(false); }
public DebuggerProxy(PhpReference reference) { _reference = reference; }
protected override void SetArrayItemRefOverride(object key, PhpReference value) { PhpException.VariableMisusedAsArray(obj, true); }
public static void GetObjectData(DObject /*!*/ instance, SerializationInfo /*!*/ info, StreamingContext strctx) { info.SetType(typeof(Deserializer)); SerializationContext context = SerializationContext.CreateFromStreamingContext(strctx); bool sleep_called; PhpArray sleep_result; // try to get the caches __sleep result if (context.SleepResults.TryGetValue(instance, out sleep_result)) { if (Object.ReferenceEquals(sleep_result, SerializationContext.NoSleepResultSingleton)) { sleep_called = false; sleep_result = null; } else { sleep_called = true; } } else { sleep_result = instance.Sleep(context.ClassContext, context.ScriptContext, out sleep_called); context.SleepResults.Add(instance, (sleep_called ? sleep_result : SerializationContext.NoSleepResultSingleton)); } if (sleep_called && sleep_result == null) { // __sleep did not return an array -> this instance will deserialize as NULL info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, String.Empty); } else { // if we have a sleep result, serialize fields according to it, otherwise serialize all fields IEnumerable <KeyValuePair <string, object> > serializable_properties; object real_object = null; if (sleep_result == null) { serializable_properties = Serialization.EnumerateSerializableProperties( instance, true); // get PHP fields only // serialize CLR real object in the "CLR way" if (!(instance is PhpObject)) { real_object = instance.RealObject; } } else { serializable_properties = Serialization.EnumerateSerializableProperties( instance, sleep_result, context.ScriptContext); } bool type_name_serialized = false; bool real_object_serialized = false; foreach (KeyValuePair <string, object> pair in serializable_properties) { if (pair.Key == __PHP_Incomplete_Class.ClassNameFieldName) { type_name_serialized = true; } if (pair.Key == ClrRealObjectSerializationInfoKey) { // unwrap the possibly wrapped CLR real object info.AddValue(pair.Key, PhpVariable.Unwrap(pair.Value)); real_object_serialized = true; } else { PhpReference reference = pair.Value as PhpReference; info.AddValue(pair.Key, WrapPropertyValue(pair.Value)); } } // if the type name has not been serialized, do it now if (!type_name_serialized) { info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, instance.TypeName); } // if the real object has not been serialized, do it now if (!real_object_serialized) { info.AddValue(ClrRealObjectSerializationInfoKey, real_object); } } }